Enter the directory of the maca folder on your drive and the name of the tissue you want to analyze.

tissue_of_interest = "Tongue"

Load the requisite packages and some additional helper functions.

library(here)
library(useful)
library(Seurat)
library(dplyr)
library(Matrix)
library(ontologyIndex)
cell_ontology = get_ontology('https://raw.githubusercontent.com/obophenotype/cell-ontology/master/cl-basic.obo', extract_tags='everything')
validate_cell_ontology = function(cell_ontology_class){
  in_cell_ontology = sapply(cell_ontology_class, function(x) is.element(x, cell_ontology$name))
  if (!all(in_cell_ontology)) {
    message = paste0('"', cell_ontology_class[!in_cell_ontology], '" is not in the cell ontology
')
    stop(message)
  }
}
convert_to_cell_ontology_id = function(cell_ontology_class){
  return(sapply(cell_ontology_class, function(x) as.vector(cell_ontology$id[cell_ontology$name == x])[1]))
}
save_dir = here('00_data_ingest', '04_tissue_robj_generated')
# read the metadata to get the plates we want
droplet_metadata_filename = here('00_data_ingest', '01_droplet_raw_data', 'metadata_droplet.csv')
droplet_metadata <- read.csv(droplet_metadata_filename, sep=",", header = TRUE)
colnames(droplet_metadata)[1] <- "channel"
droplet_metadata

Subset the metadata on the tissue.

tissue_metadata = filter(droplet_metadata, tissue == tissue_of_interest)[,c('channel','tissue','subtissue','mouse.sex')]
tissue_metadata

Use only the metadata rows corresponding to Bladder plates. Make a plate barcode dataframe to “expand” the per-plate metadata to be per-cell.

# Load the gene names and set the metadata columns by opening the first file
subfolder = paste0(tissue_of_interest, '-', tissue_metadata$channel[1])
raw.data <- Read10X(data.dir = here('00_data_ingest', '01_droplet_raw_data', 'droplet', subfolder))
colnames(raw.data) <- lapply(colnames(raw.data), function(x) paste0(tissue_metadata$channel[1], '_', x))
meta.data = data.frame(row.names = colnames(raw.data))
meta.data['channel'] = tissue_metadata$channel[1]
if (length(tissue_metadata$channel) > 1){
  # Some tissues, like Thymus and Heart had only one channel
  for(i in 2:nrow(tissue_metadata)){
    subfolder = paste0(tissue_of_interest, '-', tissue_metadata$channel[i])
    new.data <- Read10X(data.dir = here('00_data_ingest', '01_droplet_raw_data', 'droplet', subfolder))
    colnames(new.data) <- lapply(colnames(new.data), function(x) paste0(tissue_metadata$channel[i], '_', x))
    
    new.metadata = data.frame(row.names = colnames(new.data))
    new.metadata['channel'] = tissue_metadata$channel[i]
    
    raw.data = cbind(raw.data, new.data)
    meta.data = rbind(meta.data, new.metadata)
  }
}
rnames = row.names(meta.data)
meta.data <- merge(meta.data, tissue_metadata, sort = F)
row.names(meta.data) <- rnames
dim(raw.data)
[1] 23433  7538
corner(raw.data)
[1] 0 0 0 2 0
head(meta.data)

Process the raw data and load it into the Seurat object.

# Find ERCC's, compute the percent ERCC, and drop them from the raw data.
erccs <- grep(pattern = "^ERCC-", x = rownames(x = raw.data), value = TRUE)
percent.ercc <- Matrix::colSums(raw.data[erccs, ])/Matrix::colSums(raw.data)
ercc.index <- grep(pattern = "^ERCC-", x = rownames(x = raw.data), value = FALSE)
raw.data <- raw.data[-ercc.index,]
# Create the Seurat object with all the data
tiss <- CreateSeuratObject(raw.data = raw.data, project = tissue_of_interest, 
                    min.cells = 5, min.genes = 5)
tiss <- AddMetaData(object = tiss, meta.data)
tiss <- AddMetaData(object = tiss, percent.ercc, col.name = "percent.ercc")
# Change default name for sums of counts from nUMI to nReads
# colnames(tiss@meta.data)[colnames(tiss@meta.data) == 'nUMI'] <- 'nReads'
# Create metadata columns for cell_ontology_classs and subcell_ontology_classs
tiss@meta.data[,'cell_ontology_class'] <- NA
tiss@meta.data[,'subcell_ontology_class'] <- NA

Calculate percent ribosomal genes.

ribo.genes <- grep(pattern = "^Rp[sl][[:digit:]]", x = rownames(x = tiss@data), value = TRUE)
percent.ribo <- Matrix::colSums(tiss@raw.data[ribo.genes, ])/Matrix::colSums(tiss@raw.data)
tiss <- AddMetaData(object = tiss, metadata = percent.ribo, col.name = "percent.ribo")

A sanity check: genes per cell vs reads per cell.

GenePlot(object = tiss, gene1 = "nUMI", gene2 = "nGene", use.raw=T)

Filter out cells with few reads and few genes.

tiss <- FilterCells(object = tiss, subset.names = c("nGene", "nUMI"), 
    low.thresholds = c(500, 1000), high.thresholds = c(25000, 5000000))

Normalize the data, then regress out correlation with total reads

tiss <- NormalizeData(object = tiss, scale.factor = 1e4)
Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
tiss <- ScaleData(object = tiss)
[1] "Scaling data matrix"

  |                                                                                                                                      
  |                                                                                                                                |   0%
  |                                                                                                                                      
  |=========                                                                                                                       |   7%
  |                                                                                                                                      
  |=================                                                                                                               |  13%
  |                                                                                                                                      
  |==========================                                                                                                      |  20%
  |                                                                                                                                      
  |==================================                                                                                              |  27%
  |                                                                                                                                      
  |===========================================                                                                                     |  33%
  |                                                                                                                                      
  |===================================================                                                                             |  40%
  |                                                                                                                                      
  |============================================================                                                                    |  47%
  |                                                                                                                                      
  |====================================================================                                                            |  53%
  |                                                                                                                                      
  |=============================================================================                                                   |  60%
  |                                                                                                                                      
  |=====================================================================================                                           |  67%
  |                                                                                                                                      
  |==============================================================================================                                  |  73%
  |                                                                                                                                      
  |======================================================================================================                          |  80%
  |                                                                                                                                      
  |===============================================================================================================                 |  87%
  |                                                                                                                                      
  |=======================================================================================================================         |  93%
  |                                                                                                                                      
  |================================================================================================================================| 100%
tiss <- FindVariableGenes(object = tiss, do.plot = TRUE, x.high.cutoff = Inf, y.cutoff = 0.5)
Calculating gene means
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Calculating gene variance to mean ratios
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|

Run Principal Component Analysis.

tiss <- RunPCA(object = tiss, do.print = FALSE)
tiss <- ProjectPCA(object = tiss, do.print = FALSE)

Later on (in FindClusters and TSNE) you will pick a number of principal components to use. This has the effect of keeping the major directions of variation in the data and, ideally, supressing noise. There is no correct answer to the number to use, but a decent rule of thumb is to go until the plot plateaus.

PCElbowPlot(object = tiss)

Choose the number of principal components to use.

# Set number of principal components. 
n.pcs = 14

The clustering is performed based on a nearest neighbors graph. Cells that have similar expression will be joined together. The Louvain algorithm looks for groups of cells with high modularity–more connections within the group than between groups. The resolution parameter determines the scale…higher resolution will give more clusters, lower resolution will give fewer.

For the top-level clustering, aim to under-cluster instead of over-cluster. It will be easy to subset groups and further analyze them below.

# Set resolution 
res.used <- 0.5
tiss <- FindClusters(object = tiss, reduction.type = "pca", dims.use = 1:n.pcs, 
    resolution = res.used, print.output = 0, save.SNN = TRUE, force.recalc = TRUE)

To visualize

# If cells are too spread out, you can raise the perplexity. If you have few cells, try a lower perplexity (but never less than 10).
tiss <- RunTSNE(object = tiss, dims.use = 1:n.pcs, seed.use = 20, perplexity=35, dim.embed = 2)
TSNEPlot(object = tiss, do.label = T, pt.size = 1.2, label.size = 4)

Save the Robject for later

When you save the annotated tissue, please give it a name.

filename = here('00_data_ingest', '04_tissue_robj_generated', 
          paste0("droplet", tissue_of_interest, "_seurat_tiss.Robj"))
print(filename)
[1] "/Users/Jintonic/Documents/GitHub/tabula-muris/00_data_ingest/04_tissue_robj_generated/dropletTongue_seurat_tiss.Robj"
save(tiss, file=filename)

Check expression of genes of interset.

Dotplots let you see the intensity of exppression and the fraction of cells expressing for each of your genes of interest.

How big are the clusters?

table(tiss@ident)

   0    1    2    3    4    5    6    7    8    9   10 
1653 1377  853  780  698  589  489  471  389  202   37 
tiss1=BuildClusterTree(tiss)
[1] "Finished averaging RNA for cluster 0"
[1] "Finished averaging RNA for cluster 1"
[1] "Finished averaging RNA for cluster 2"
[1] "Finished averaging RNA for cluster 3"
[1] "Finished averaging RNA for cluster 4"
[1] "Finished averaging RNA for cluster 5"
[1] "Finished averaging RNA for cluster 6"
[1] "Finished averaging RNA for cluster 7"
[1] "Finished averaging RNA for cluster 8"
[1] "Finished averaging RNA for cluster 9"
[1] "Finished averaging RNA for cluster 10"

#cluster1.markers <- FindMarkers(object = tiss, ident.1 = 1, min.pct = 0.25, only.pos = TRUE, thresh.use = 0.25)
#cluster2.markers <- FindMarkers(object = tiss, ident.1 = 2, min.pct = 0.25, only.pos = TRUE, thresh.use = 0.25)
#cluster3.markers <- FindMarkers(object = tiss, ident.1 = 3, min.pct = 0.25, only.pos = TRUE, thresh.use = 0.25)
#cluster4.markers <- FindMarkers(object = tiss, ident.1 = 4, min.pct = 0.25, only.pos = TRUE, thresh.use = 0.25)
#cluster5.markers <- FindMarkers(object = tiss, ident.1 = 5, min.pct = 0.25, only.pos = TRUE, thresh.use = 0.25)
cluster6.markers <- FindMarkers(object = tiss, ident.1 = 6, min.pct = 0.25, only.pos = TRUE, thresh.use = 0.25)

   |                                                  | 0 % ~calculating  
   |+                                                 | 2 % ~20s          
   |++                                                | 4 % ~19s          
   |+++                                               | 6 % ~18s          
   |++++                                              | 8 % ~18s          
   |+++++                                             | 10% ~17s          
   |++++++                                            | 12% ~17s          
   |+++++++                                           | 14% ~16s          
   |++++++++                                          | 16% ~16s          
   |+++++++++                                         | 18% ~16s          
   |++++++++++                                        | 20% ~19s          
   |+++++++++++                                       | 22% ~18s          
   |++++++++++++                                      | 24% ~17s          
   |+++++++++++++                                     | 25% ~17s          
   |++++++++++++++                                    | 27% ~16s          
   |+++++++++++++++                                   | 29% ~16s          
   |++++++++++++++++                                  | 31% ~15s          
   |+++++++++++++++++                                 | 33% ~14s          
   |++++++++++++++++++                                | 35% ~14s          
   |+++++++++++++++++++                               | 37% ~13s          
   |++++++++++++++++++++                              | 39% ~13s          
   |+++++++++++++++++++++                             | 41% ~12s          
   |++++++++++++++++++++++                            | 43% ~12s          
   |+++++++++++++++++++++++                           | 45% ~11s          
   |++++++++++++++++++++++++                          | 47% ~11s          
   |+++++++++++++++++++++++++                         | 49% ~11s          
   |++++++++++++++++++++++++++                        | 51% ~10s          
   |+++++++++++++++++++++++++++                       | 53% ~10s          
   |++++++++++++++++++++++++++++                      | 55% ~09s          
   |+++++++++++++++++++++++++++++                     | 57% ~09s          
   |++++++++++++++++++++++++++++++                    | 59% ~08s          
   |+++++++++++++++++++++++++++++++                   | 61% ~08s          
   |++++++++++++++++++++++++++++++++                  | 63% ~08s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~07s          
   |++++++++++++++++++++++++++++++++++                | 67% ~07s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~06s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~06s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~06s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~05s          
   |+++++++++++++++++++++++++++++++++++++++           | 76% ~05s          
   |++++++++++++++++++++++++++++++++++++++++          | 78% ~04s          
   |+++++++++++++++++++++++++++++++++++++++++         | 80% ~04s          
   |++++++++++++++++++++++++++++++++++++++++++        | 82% ~04s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 84% ~03s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 90% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 92% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 94% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 96% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 98% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 20s
#cluster7.markers <- FindMarkers(object = tiss, ident.1 = 7, min.pct = 0.25, only.pos = TRUE, thresh.use = 0.25)
#cluster8.markers <- FindMarkers(object = tiss, ident.1 = 8, min.pct = 0.25, only.pos = TRUE, thresh.use = 0.25)
#cluster9.markers <- FindMarkers(object = tiss, ident.1 = 9, min.pct = 0.25, only.pos = TRUE, thresh.use = 0.25)
#cluster0.markers <- FindMarkers(object = tiss, ident.1 = 0, min.pct = 0.25, only.pos = TRUE, thresh.use = 0.25)

Which markers identify a specific cluster?

print(x = head(x = cluster6.markers, n = 30))

You can also compute all markers for all clusters at once. This may take some time.

tiss.markers <- FindAllMarkers(object = tiss, only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25)

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~01m 08s      
   |++                                                | 2 % ~01m 05s      
   |++                                                | 3 % ~01m 05s      
   |+++                                               | 4 % ~01m 05s      
   |+++                                               | 6 % ~01m 04s      
   |++++                                              | 7 % ~01m 04s      
   |++++                                              | 8 % ~01m 03s      
   |+++++                                             | 9 % ~01m 02s      
   |++++++                                            | 10% ~01m 01s      
   |++++++                                            | 11% ~01m 01s      
   |+++++++                                           | 12% ~60s          
   |+++++++                                           | 13% ~59s          
   |++++++++                                          | 15% ~58s          
   |++++++++                                          | 16% ~57s          
   |+++++++++                                         | 17% ~56s          
   |+++++++++                                         | 18% ~56s          
   |++++++++++                                        | 19% ~55s          
   |+++++++++++                                       | 20% ~54s          
   |+++++++++++                                       | 21% ~53s          
   |++++++++++++                                      | 22% ~53s          
   |++++++++++++                                      | 24% ~52s          
   |+++++++++++++                                     | 25% ~51s          
   |+++++++++++++                                     | 26% ~51s          
   |++++++++++++++                                    | 27% ~50s          
   |+++++++++++++++                                   | 28% ~49s          
   |+++++++++++++++                                   | 29% ~48s          
   |++++++++++++++++                                  | 30% ~48s          
   |++++++++++++++++                                  | 31% ~48s          
   |+++++++++++++++++                                 | 33% ~47s          
   |+++++++++++++++++                                 | 34% ~46s          
   |++++++++++++++++++                                | 35% ~46s          
   |++++++++++++++++++                                | 36% ~45s          
   |+++++++++++++++++++                               | 37% ~44s          
   |++++++++++++++++++++                              | 38% ~43s          
   |++++++++++++++++++++                              | 39% ~42s          
   |+++++++++++++++++++++                             | 40% ~41s          
   |+++++++++++++++++++++                             | 42% ~41s          
   |++++++++++++++++++++++                            | 43% ~40s          
   |++++++++++++++++++++++                            | 44% ~39s          
   |+++++++++++++++++++++++                           | 45% ~38s          
   |++++++++++++++++++++++++                          | 46% ~37s          
   |++++++++++++++++++++++++                          | 47% ~36s          
   |+++++++++++++++++++++++++                         | 48% ~36s          
   |+++++++++++++++++++++++++                         | 49% ~35s          
   |++++++++++++++++++++++++++                        | 51% ~34s          
   |++++++++++++++++++++++++++                        | 52% ~33s          
   |+++++++++++++++++++++++++++                       | 53% ~33s          
   |+++++++++++++++++++++++++++                       | 54% ~32s          
   |++++++++++++++++++++++++++++                      | 55% ~31s          
   |+++++++++++++++++++++++++++++                     | 56% ~30s          
   |+++++++++++++++++++++++++++++                     | 57% ~29s          
   |++++++++++++++++++++++++++++++                    | 58% ~29s          
   |++++++++++++++++++++++++++++++                    | 60% ~28s          
   |+++++++++++++++++++++++++++++++                   | 61% ~27s          
   |+++++++++++++++++++++++++++++++                   | 62% ~26s          
   |++++++++++++++++++++++++++++++++                  | 63% ~26s          
   |+++++++++++++++++++++++++++++++++                 | 64% ~25s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~24s          
   |++++++++++++++++++++++++++++++++++                | 66% ~23s          
   |++++++++++++++++++++++++++++++++++                | 67% ~22s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~22s          
   |+++++++++++++++++++++++++++++++++++               | 70% ~21s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~20s          
   |++++++++++++++++++++++++++++++++++++              | 72% ~19s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~19s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~18s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~17s          
   |+++++++++++++++++++++++++++++++++++++++           | 76% ~16s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~15s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~15s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~14s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~13s          
   |++++++++++++++++++++++++++++++++++++++++++        | 82% ~12s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~12s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 84% ~11s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~10s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~09s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~08s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~08s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~07s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~06s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 92% ~05s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~05s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 94% ~04s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 01m 09s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~01m 17s      
   |++                                                | 2 % ~01m 14s      
   |++                                                | 3 % ~01m 12s      
   |+++                                               | 4 % ~01m 12s      
   |+++                                               | 5 % ~01m 11s      
   |++++                                              | 6 % ~01m 11s      
   |++++                                              | 7 % ~01m 10s      
   |+++++                                             | 8 % ~01m 09s      
   |+++++                                             | 9 % ~01m 09s      
   |++++++                                            | 10% ~01m 08s      
   |++++++                                            | 11% ~01m 07s      
   |+++++++                                           | 12% ~01m 06s      
   |+++++++                                           | 13% ~01m 06s      
   |++++++++                                          | 14% ~01m 05s      
   |++++++++                                          | 15% ~01m 04s      
   |+++++++++                                         | 16% ~01m 03s      
   |+++++++++                                         | 17% ~01m 02s      
   |++++++++++                                        | 18% ~01m 09s      
   |++++++++++                                        | 19% ~01m 08s      
   |+++++++++++                                       | 20% ~01m 07s      
   |+++++++++++                                       | 21% ~01m 06s      
   |++++++++++++                                      | 22% ~01m 05s      
   |++++++++++++                                      | 23% ~01m 03s      
   |+++++++++++++                                     | 24% ~01m 02s      
   |+++++++++++++                                     | 25% ~01m 01s      
   |++++++++++++++                                    | 26% ~01m 00s      
   |++++++++++++++                                    | 27% ~59s          
   |+++++++++++++++                                   | 28% ~58s          
   |+++++++++++++++                                   | 29% ~57s          
   |++++++++++++++++                                  | 30% ~56s          
   |++++++++++++++++                                  | 31% ~55s          
   |+++++++++++++++++                                 | 32% ~54s          
   |+++++++++++++++++                                 | 33% ~53s          
   |++++++++++++++++++                                | 34% ~52s          
   |++++++++++++++++++                                | 35% ~51s          
   |+++++++++++++++++++                               | 36% ~51s          
   |+++++++++++++++++++                               | 37% ~50s          
   |++++++++++++++++++++                              | 38% ~49s          
   |++++++++++++++++++++                              | 39% ~48s          
   |+++++++++++++++++++++                             | 40% ~47s          
   |+++++++++++++++++++++                             | 41% ~46s          
   |++++++++++++++++++++++                            | 42% ~45s          
   |++++++++++++++++++++++                            | 43% ~44s          
   |+++++++++++++++++++++++                           | 44% ~44s          
   |+++++++++++++++++++++++                           | 45% ~43s          
   |++++++++++++++++++++++++                          | 46% ~42s          
   |++++++++++++++++++++++++                          | 47% ~41s          
   |+++++++++++++++++++++++++                         | 48% ~40s          
   |+++++++++++++++++++++++++                         | 49% ~39s          
   |++++++++++++++++++++++++++                        | 51% ~39s          
   |++++++++++++++++++++++++++                        | 52% ~38s          
   |+++++++++++++++++++++++++++                       | 53% ~37s          
   |+++++++++++++++++++++++++++                       | 54% ~36s          
   |++++++++++++++++++++++++++++                      | 55% ~35s          
   |++++++++++++++++++++++++++++                      | 56% ~34s          
   |+++++++++++++++++++++++++++++                     | 57% ~34s          
   |+++++++++++++++++++++++++++++                     | 58% ~33s          
   |++++++++++++++++++++++++++++++                    | 59% ~32s          
   |++++++++++++++++++++++++++++++                    | 60% ~31s          
   |+++++++++++++++++++++++++++++++                   | 61% ~30s          
   |+++++++++++++++++++++++++++++++                   | 62% ~30s          
   |++++++++++++++++++++++++++++++++                  | 63% ~29s          
   |++++++++++++++++++++++++++++++++                  | 64% ~28s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~27s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~26s          
   |++++++++++++++++++++++++++++++++++                | 67% ~26s          
   |++++++++++++++++++++++++++++++++++                | 68% ~25s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~24s          
   |+++++++++++++++++++++++++++++++++++               | 70% ~23s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~23s          
   |++++++++++++++++++++++++++++++++++++              | 72% ~22s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~21s          
   |+++++++++++++++++++++++++++++++++++++             | 74% ~20s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~19s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~19s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~18s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~17s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~16s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~15s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~15s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~14s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~13s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~12s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~12s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~11s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~10s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~09s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~08s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~07s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~06s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~05s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~05s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~04s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 01m 16s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~02m 08s      
   |++                                                | 2 % ~02m 07s      
   |++                                                | 3 % ~02m 04s      
   |+++                                               | 4 % ~02m 02s      
   |+++                                               | 5 % ~02m 01s      
   |++++                                              | 6 % ~01m 60s      
   |++++                                              | 7 % ~02m 04s      
   |+++++                                             | 8 % ~02m 01s      
   |+++++                                             | 9 % ~01m 59s      
   |++++++                                            | 10% ~01m 57s      
   |++++++                                            | 11% ~01m 56s      
   |+++++++                                           | 12% ~01m 54s      
   |+++++++                                           | 14% ~01m 52s      
   |++++++++                                          | 15% ~01m 50s      
   |++++++++                                          | 16% ~01m 49s      
   |+++++++++                                         | 17% ~01m 47s      
   |+++++++++                                         | 18% ~01m 46s      
   |++++++++++                                        | 19% ~01m 45s      
   |++++++++++                                        | 20% ~01m 44s      
   |+++++++++++                                       | 21% ~01m 42s      
   |+++++++++++                                       | 22% ~01m 41s      
   |++++++++++++                                      | 23% ~01m 39s      
   |++++++++++++                                      | 24% ~01m 38s      
   |+++++++++++++                                     | 25% ~01m 36s      
   |++++++++++++++                                    | 26% ~01m 35s      
   |++++++++++++++                                    | 27% ~01m 33s      
   |+++++++++++++++                                   | 28% ~01m 32s      
   |+++++++++++++++                                   | 29% ~01m 31s      
   |++++++++++++++++                                  | 30% ~01m 29s      
   |++++++++++++++++                                  | 31% ~01m 28s      
   |+++++++++++++++++                                 | 32% ~01m 27s      
   |+++++++++++++++++                                 | 33% ~01m 25s      
   |++++++++++++++++++                                | 34% ~01m 24s      
   |++++++++++++++++++                                | 35% ~01m 23s      
   |+++++++++++++++++++                               | 36% ~01m 21s      
   |+++++++++++++++++++                               | 38% ~01m 20s      
   |++++++++++++++++++++                              | 39% ~01m 18s      
   |++++++++++++++++++++                              | 40% ~01m 17s      
   |+++++++++++++++++++++                             | 41% ~01m 16s      
   |+++++++++++++++++++++                             | 42% ~01m 15s      
   |++++++++++++++++++++++                            | 43% ~01m 13s      
   |++++++++++++++++++++++                            | 44% ~01m 12s      
   |+++++++++++++++++++++++                           | 45% ~01m 11s      
   |+++++++++++++++++++++++                           | 46% ~01m 10s      
   |++++++++++++++++++++++++                          | 47% ~01m 09s      
   |++++++++++++++++++++++++                          | 48% ~01m 07s      
   |+++++++++++++++++++++++++                         | 49% ~01m 06s      
   |+++++++++++++++++++++++++                         | 50% ~01m 05s      
   |++++++++++++++++++++++++++                        | 51% ~01m 03s      
   |+++++++++++++++++++++++++++                       | 52% ~01m 02s      
   |+++++++++++++++++++++++++++                       | 53% ~01m 01s      
   |++++++++++++++++++++++++++++                      | 54% ~59s          
   |++++++++++++++++++++++++++++                      | 55% ~58s          
   |+++++++++++++++++++++++++++++                     | 56% ~56s          
   |+++++++++++++++++++++++++++++                     | 57% ~55s          
   |++++++++++++++++++++++++++++++                    | 58% ~54s          
   |++++++++++++++++++++++++++++++                    | 59% ~52s          
   |+++++++++++++++++++++++++++++++                   | 60% ~51s          
   |+++++++++++++++++++++++++++++++                   | 61% ~50s          
   |++++++++++++++++++++++++++++++++                  | 62% ~48s          
   |++++++++++++++++++++++++++++++++                  | 64% ~47s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~46s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~44s          
   |++++++++++++++++++++++++++++++++++                | 67% ~43s          
   |++++++++++++++++++++++++++++++++++                | 68% ~42s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~40s          
   |+++++++++++++++++++++++++++++++++++               | 70% ~39s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~38s          
   |++++++++++++++++++++++++++++++++++++              | 72% ~36s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~35s          
   |+++++++++++++++++++++++++++++++++++++             | 74% ~34s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~32s          
   |+++++++++++++++++++++++++++++++++++++++           | 76% ~31s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~30s          
   |++++++++++++++++++++++++++++++++++++++++          | 78% ~28s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~27s          
   |+++++++++++++++++++++++++++++++++++++++++         | 80% ~26s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~24s          
   |++++++++++++++++++++++++++++++++++++++++++        | 82% ~23s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~22s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 84% ~20s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~19s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~18s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~16s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~15s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~13s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~12s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~11s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~09s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~07s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~05s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~04s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~03s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 02m 10s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~02m 46s      
   |++                                                | 2 % ~02m 44s      
   |++                                                | 3 % ~02m 41s      
   |+++                                               | 4 % ~02m 40s      
   |+++                                               | 5 % ~02m 38s      
   |++++                                              | 6 % ~02m 36s      
   |++++                                              | 7 % ~02m 35s      
   |+++++                                             | 8 % ~02m 34s      
   |+++++                                             | 9 % ~02m 33s      
   |++++++                                            | 10% ~02m 31s      
   |++++++                                            | 11% ~02m 30s      
   |+++++++                                           | 12% ~02m 28s      
   |+++++++                                           | 14% ~02m 29s      
   |++++++++                                          | 15% ~02m 27s      
   |++++++++                                          | 16% ~02m 25s      
   |+++++++++                                         | 17% ~02m 23s      
   |+++++++++                                         | 18% ~02m 24s      
   |++++++++++                                        | 19% ~02m 22s      
   |++++++++++                                        | 20% ~02m 20s      
   |+++++++++++                                       | 21% ~02m 17s      
   |+++++++++++                                       | 22% ~02m 16s      
   |++++++++++++                                      | 23% ~02m 13s      
   |++++++++++++                                      | 24% ~02m 11s      
   |+++++++++++++                                     | 25% ~02m 09s      
   |++++++++++++++                                    | 26% ~02m 07s      
   |++++++++++++++                                    | 27% ~02m 05s      
   |+++++++++++++++                                   | 28% ~02m 03s      
   |+++++++++++++++                                   | 29% ~02m 01s      
   |++++++++++++++++                                  | 30% ~01m 59s      
   |++++++++++++++++                                  | 31% ~01m 58s      
   |+++++++++++++++++                                 | 32% ~01m 56s      
   |+++++++++++++++++                                 | 33% ~01m 54s      
   |++++++++++++++++++                                | 34% ~01m 52s      
   |++++++++++++++++++                                | 35% ~01m 51s      
   |+++++++++++++++++++                               | 36% ~01m 49s      
   |+++++++++++++++++++                               | 38% ~01m 47s      
   |++++++++++++++++++++                              | 39% ~01m 45s      
   |++++++++++++++++++++                              | 40% ~01m 43s      
   |+++++++++++++++++++++                             | 41% ~01m 41s      
   |+++++++++++++++++++++                             | 42% ~01m 40s      
   |++++++++++++++++++++++                            | 43% ~01m 38s      
   |++++++++++++++++++++++                            | 44% ~01m 36s      
   |+++++++++++++++++++++++                           | 45% ~01m 34s      
   |+++++++++++++++++++++++                           | 46% ~01m 32s      
   |++++++++++++++++++++++++                          | 47% ~01m 30s      
   |++++++++++++++++++++++++                          | 48% ~01m 29s      
   |+++++++++++++++++++++++++                         | 49% ~01m 27s      
   |+++++++++++++++++++++++++                         | 50% ~01m 25s      
   |++++++++++++++++++++++++++                        | 51% ~01m 23s      
   |+++++++++++++++++++++++++++                       | 52% ~01m 22s      
   |+++++++++++++++++++++++++++                       | 53% ~01m 20s      
   |++++++++++++++++++++++++++++                      | 54% ~01m 18s      
   |++++++++++++++++++++++++++++                      | 55% ~01m 16s      
   |+++++++++++++++++++++++++++++                     | 56% ~01m 14s      
   |+++++++++++++++++++++++++++++                     | 57% ~01m 13s      
   |++++++++++++++++++++++++++++++                    | 58% ~01m 12s      
   |++++++++++++++++++++++++++++++                    | 59% ~01m 10s      
   |+++++++++++++++++++++++++++++++                   | 60% ~01m 08s      
   |+++++++++++++++++++++++++++++++                   | 61% ~01m 06s      
   |++++++++++++++++++++++++++++++++                  | 62% ~01m 04s      
   |++++++++++++++++++++++++++++++++                  | 64% ~01m 02s      
   |+++++++++++++++++++++++++++++++++                 | 65% ~01m 01s      
   |+++++++++++++++++++++++++++++++++                 | 66% ~59s          
   |++++++++++++++++++++++++++++++++++                | 67% ~57s          
   |++++++++++++++++++++++++++++++++++                | 68% ~55s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~54s          
   |+++++++++++++++++++++++++++++++++++               | 70% ~52s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~50s          
   |++++++++++++++++++++++++++++++++++++              | 72% ~49s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~47s          
   |+++++++++++++++++++++++++++++++++++++             | 74% ~45s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~43s          
   |+++++++++++++++++++++++++++++++++++++++           | 76% ~41s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~40s          
   |++++++++++++++++++++++++++++++++++++++++          | 78% ~38s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~36s          
   |+++++++++++++++++++++++++++++++++++++++++         | 80% ~34s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~32s          
   |++++++++++++++++++++++++++++++++++++++++++        | 82% ~31s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~29s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 84% ~27s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~25s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~23s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~22s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~20s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~18s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~16s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~14s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~13s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~11s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~09s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~07s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~05s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~04s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 02m 52s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~01m 20s      
   |++                                                | 2 % ~01m 18s      
   |++                                                | 3 % ~01m 16s      
   |+++                                               | 5 % ~01m 16s      
   |+++                                               | 6 % ~01m 15s      
   |++++                                              | 7 % ~01m 14s      
   |+++++                                             | 8 % ~01m 14s      
   |+++++                                             | 9 % ~01m 13s      
   |++++++                                            | 10% ~01m 12s      
   |++++++                                            | 12% ~01m 11s      
   |+++++++                                           | 13% ~01m 10s      
   |+++++++                                           | 14% ~01m 09s      
   |++++++++                                          | 15% ~01m 08s      
   |+++++++++                                         | 16% ~01m 07s      
   |+++++++++                                         | 17% ~01m 06s      
   |++++++++++                                        | 19% ~01m 05s      
   |++++++++++                                        | 20% ~01m 04s      
   |+++++++++++                                       | 21% ~01m 05s      
   |++++++++++++                                      | 22% ~01m 05s      
   |++++++++++++                                      | 23% ~01m 04s      
   |+++++++++++++                                     | 24% ~01m 03s      
   |+++++++++++++                                     | 26% ~01m 02s      
   |++++++++++++++                                    | 27% ~01m 01s      
   |++++++++++++++                                    | 28% ~01m 00s      
   |+++++++++++++++                                   | 29% ~59s          
   |++++++++++++++++                                  | 30% ~58s          
   |++++++++++++++++                                  | 31% ~57s          
   |+++++++++++++++++                                 | 33% ~56s          
   |+++++++++++++++++                                 | 34% ~55s          
   |++++++++++++++++++                                | 35% ~54s          
   |+++++++++++++++++++                               | 36% ~53s          
   |+++++++++++++++++++                               | 37% ~52s          
   |++++++++++++++++++++                              | 38% ~51s          
   |++++++++++++++++++++                              | 40% ~50s          
   |+++++++++++++++++++++                             | 41% ~49s          
   |+++++++++++++++++++++                             | 42% ~48s          
   |++++++++++++++++++++++                            | 43% ~47s          
   |+++++++++++++++++++++++                           | 44% ~46s          
   |+++++++++++++++++++++++                           | 45% ~45s          
   |++++++++++++++++++++++++                          | 47% ~44s          
   |++++++++++++++++++++++++                          | 48% ~43s          
   |+++++++++++++++++++++++++                         | 49% ~42s          
   |+++++++++++++++++++++++++                         | 50% ~41s          
   |++++++++++++++++++++++++++                        | 51% ~40s          
   |+++++++++++++++++++++++++++                       | 52% ~39s          
   |+++++++++++++++++++++++++++                       | 53% ~38s          
   |++++++++++++++++++++++++++++                      | 55% ~38s          
   |++++++++++++++++++++++++++++                      | 56% ~37s          
   |+++++++++++++++++++++++++++++                     | 57% ~36s          
   |++++++++++++++++++++++++++++++                    | 58% ~35s          
   |++++++++++++++++++++++++++++++                    | 59% ~34s          
   |+++++++++++++++++++++++++++++++                   | 60% ~33s          
   |+++++++++++++++++++++++++++++++                   | 62% ~32s          
   |++++++++++++++++++++++++++++++++                  | 63% ~31s          
   |++++++++++++++++++++++++++++++++                  | 64% ~30s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~29s          
   |++++++++++++++++++++++++++++++++++                | 66% ~28s          
   |++++++++++++++++++++++++++++++++++                | 67% ~27s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~26s          
   |+++++++++++++++++++++++++++++++++++               | 70% ~25s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~24s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~23s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~22s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~21s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~20s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~19s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~18s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~17s          
   |+++++++++++++++++++++++++++++++++++++++++         | 80% ~16s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~15s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~14s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~14s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~13s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~12s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~11s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~10s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~09s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~07s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~06s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 94% ~05s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~04s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 01m 25s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~02m 15s      
   |++                                                | 2 % ~02m 14s      
   |++                                                | 3 % ~02m 12s      
   |+++                                               | 4 % ~02m 11s      
   |+++                                               | 5 % ~02m 10s      
   |++++                                              | 7 % ~02m 08s      
   |++++                                              | 8 % ~02m 07s      
   |+++++                                             | 9 % ~02m 06s      
   |+++++                                             | 10% ~02m 04s      
   |++++++                                            | 11% ~02m 03s      
   |++++++                                            | 12% ~02m 01s      
   |+++++++                                           | 13% ~01m 60s      
   |++++++++                                          | 14% ~01m 59s      
   |++++++++                                          | 15% ~01m 57s      
   |+++++++++                                         | 16% ~01m 56s      
   |+++++++++                                         | 17% ~01m 54s      
   |++++++++++                                        | 18% ~01m 53s      
   |++++++++++                                        | 20% ~01m 51s      
   |+++++++++++                                       | 21% ~01m 50s      
   |+++++++++++                                       | 22% ~01m 48s      
   |++++++++++++                                      | 23% ~01m 47s      
   |++++++++++++                                      | 24% ~01m 45s      
   |+++++++++++++                                     | 25% ~01m 44s      
   |++++++++++++++                                    | 26% ~01m 42s      
   |++++++++++++++                                    | 27% ~01m 41s      
   |+++++++++++++++                                   | 28% ~01m 39s      
   |+++++++++++++++                                   | 29% ~01m 38s      
   |++++++++++++++++                                  | 30% ~01m 36s      
   |++++++++++++++++                                  | 32% ~01m 35s      
   |+++++++++++++++++                                 | 33% ~01m 33s      
   |+++++++++++++++++                                 | 34% ~01m 32s      
   |++++++++++++++++++                                | 35% ~01m 30s      
   |++++++++++++++++++                                | 36% ~01m 29s      
   |+++++++++++++++++++                               | 37% ~01m 27s      
   |++++++++++++++++++++                              | 38% ~01m 26s      
   |++++++++++++++++++++                              | 39% ~01m 24s      
   |+++++++++++++++++++++                             | 40% ~01m 23s      
   |+++++++++++++++++++++                             | 41% ~01m 21s      
   |++++++++++++++++++++++                            | 42% ~01m 20s      
   |++++++++++++++++++++++                            | 43% ~01m 18s      
   |+++++++++++++++++++++++                           | 45% ~01m 17s      
   |+++++++++++++++++++++++                           | 46% ~01m 15s      
   |++++++++++++++++++++++++                          | 47% ~01m 15s      
   |++++++++++++++++++++++++                          | 48% ~01m 13s      
   |+++++++++++++++++++++++++                         | 49% ~01m 12s      
   |+++++++++++++++++++++++++                         | 50% ~01m 10s      
   |++++++++++++++++++++++++++                        | 51% ~01m 08s      
   |+++++++++++++++++++++++++++                       | 52% ~01m 07s      
   |+++++++++++++++++++++++++++                       | 53% ~01m 05s      
   |++++++++++++++++++++++++++++                      | 54% ~01m 04s      
   |++++++++++++++++++++++++++++                      | 55% ~01m 02s      
   |+++++++++++++++++++++++++++++                     | 57% ~01m 01s      
   |+++++++++++++++++++++++++++++                     | 58% ~59s          
   |++++++++++++++++++++++++++++++                    | 59% ~58s          
   |++++++++++++++++++++++++++++++                    | 60% ~56s          
   |+++++++++++++++++++++++++++++++                   | 61% ~55s          
   |+++++++++++++++++++++++++++++++                   | 62% ~53s          
   |++++++++++++++++++++++++++++++++                  | 63% ~52s          
   |+++++++++++++++++++++++++++++++++                 | 64% ~50s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~49s          
   |++++++++++++++++++++++++++++++++++                | 66% ~47s          
   |++++++++++++++++++++++++++++++++++                | 67% ~46s          
   |+++++++++++++++++++++++++++++++++++               | 68% ~44s          
   |+++++++++++++++++++++++++++++++++++               | 70% ~43s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~41s          
   |++++++++++++++++++++++++++++++++++++              | 72% ~40s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~38s          
   |+++++++++++++++++++++++++++++++++++++             | 74% ~37s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~35s          
   |+++++++++++++++++++++++++++++++++++++++           | 76% ~34s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~32s          
   |++++++++++++++++++++++++++++++++++++++++          | 78% ~31s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~29s          
   |+++++++++++++++++++++++++++++++++++++++++         | 80% ~28s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~26s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~24s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~23s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~22s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~20s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~18s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~17s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~15s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 90% ~14s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~12s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 92% ~11s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~09s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~06s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~05s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~03s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 02m 20s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~57s          
   |++                                                | 3 % ~57s          
   |++                                                | 4 % ~56s          
   |+++                                               | 5 % ~56s          
   |++++                                              | 6 % ~55s          
   |++++                                              | 8 % ~54s          
   |+++++                                             | 9 % ~53s          
   |++++++                                            | 10% ~53s          
   |++++++                                            | 11% ~52s          
   |+++++++                                           | 13% ~51s          
   |+++++++                                           | 14% ~51s          
   |++++++++                                          | 15% ~50s          
   |+++++++++                                         | 16% ~49s          
   |+++++++++                                         | 18% ~48s          
   |++++++++++                                        | 19% ~48s          
   |+++++++++++                                       | 20% ~47s          
   |+++++++++++                                       | 22% ~46s          
   |++++++++++++                                      | 23% ~45s          
   |+++++++++++++                                     | 24% ~44s          
   |+++++++++++++                                     | 25% ~44s          
   |++++++++++++++                                    | 27% ~43s          
   |++++++++++++++                                    | 28% ~42s          
   |+++++++++++++++                                   | 29% ~42s          
   |++++++++++++++++                                  | 30% ~41s          
   |++++++++++++++++                                  | 32% ~40s          
   |+++++++++++++++++                                 | 33% ~39s          
   |++++++++++++++++++                                | 34% ~39s          
   |++++++++++++++++++                                | 35% ~38s          
   |+++++++++++++++++++                               | 37% ~37s          
   |+++++++++++++++++++                               | 38% ~36s          
   |++++++++++++++++++++                              | 39% ~36s          
   |+++++++++++++++++++++                             | 41% ~35s          
   |+++++++++++++++++++++                             | 42% ~34s          
   |++++++++++++++++++++++                            | 43% ~33s          
   |+++++++++++++++++++++++                           | 44% ~33s          
   |+++++++++++++++++++++++                           | 46% ~32s          
   |++++++++++++++++++++++++                          | 47% ~31s          
   |+++++++++++++++++++++++++                         | 48% ~30s          
   |+++++++++++++++++++++++++                         | 49% ~30s          
   |++++++++++++++++++++++++++                        | 51% ~29s          
   |++++++++++++++++++++++++++                        | 52% ~28s          
   |+++++++++++++++++++++++++++                       | 53% ~27s          
   |++++++++++++++++++++++++++++                      | 54% ~27s          
   |++++++++++++++++++++++++++++                      | 56% ~26s          
   |+++++++++++++++++++++++++++++                     | 57% ~25s          
   |++++++++++++++++++++++++++++++                    | 58% ~24s          
   |++++++++++++++++++++++++++++++                    | 59% ~24s          
   |+++++++++++++++++++++++++++++++                   | 61% ~23s          
   |++++++++++++++++++++++++++++++++                  | 62% ~22s          
   |++++++++++++++++++++++++++++++++                  | 63% ~22s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~21s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~20s          
   |++++++++++++++++++++++++++++++++++                | 67% ~20s          
   |+++++++++++++++++++++++++++++++++++               | 68% ~19s          
   |+++++++++++++++++++++++++++++++++++               | 70% ~18s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~17s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~17s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~16s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~15s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~14s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~14s          
   |++++++++++++++++++++++++++++++++++++++++          | 78% ~13s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~12s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~11s          
   |++++++++++++++++++++++++++++++++++++++++++        | 82% ~11s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~10s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~09s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~08s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~07s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~06s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~05s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 92% ~05s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~04s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 96% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 59s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~01m 27s      
   |++                                                | 2 % ~01m 25s      
   |++                                                | 3 % ~01m 31s      
   |+++                                               | 4 % ~01m 29s      
   |+++                                               | 6 % ~01m 26s      
   |++++                                              | 7 % ~01m 24s      
   |++++                                              | 8 % ~01m 23s      
   |+++++                                             | 9 % ~01m 21s      
   |+++++                                             | 10% ~01m 20s      
   |++++++                                            | 11% ~01m 18s      
   |+++++++                                           | 12% ~01m 17s      
   |+++++++                                           | 13% ~01m 16s      
   |++++++++                                          | 14% ~01m 15s      
   |++++++++                                          | 16% ~01m 14s      
   |+++++++++                                         | 17% ~01m 13s      
   |+++++++++                                         | 18% ~01m 11s      
   |++++++++++                                        | 19% ~01m 10s      
   |++++++++++                                        | 20% ~01m 09s      
   |+++++++++++                                       | 21% ~01m 08s      
   |++++++++++++                                      | 22% ~01m 07s      
   |++++++++++++                                      | 23% ~01m 06s      
   |+++++++++++++                                     | 24% ~01m 05s      
   |+++++++++++++                                     | 26% ~01m 04s      
   |++++++++++++++                                    | 27% ~01m 03s      
   |++++++++++++++                                    | 28% ~01m 02s      
   |+++++++++++++++                                   | 29% ~01m 01s      
   |+++++++++++++++                                   | 30% ~01m 01s      
   |++++++++++++++++                                  | 31% ~60s          
   |+++++++++++++++++                                 | 32% ~59s          
   |+++++++++++++++++                                 | 33% ~58s          
   |++++++++++++++++++                                | 34% ~57s          
   |++++++++++++++++++                                | 36% ~56s          
   |+++++++++++++++++++                               | 37% ~55s          
   |+++++++++++++++++++                               | 38% ~54s          
   |++++++++++++++++++++                              | 39% ~53s          
   |++++++++++++++++++++                              | 40% ~52s          
   |+++++++++++++++++++++                             | 41% ~51s          
   |++++++++++++++++++++++                            | 42% ~50s          
   |++++++++++++++++++++++                            | 43% ~49s          
   |+++++++++++++++++++++++                           | 44% ~48s          
   |+++++++++++++++++++++++                           | 46% ~47s          
   |++++++++++++++++++++++++                          | 47% ~46s          
   |++++++++++++++++++++++++                          | 48% ~45s          
   |+++++++++++++++++++++++++                         | 49% ~44s          
   |+++++++++++++++++++++++++                         | 50% ~43s          
   |++++++++++++++++++++++++++                        | 51% ~42s          
   |+++++++++++++++++++++++++++                       | 52% ~41s          
   |+++++++++++++++++++++++++++                       | 53% ~40s          
   |++++++++++++++++++++++++++++                      | 54% ~39s          
   |++++++++++++++++++++++++++++                      | 56% ~38s          
   |+++++++++++++++++++++++++++++                     | 57% ~37s          
   |+++++++++++++++++++++++++++++                     | 58% ~36s          
   |++++++++++++++++++++++++++++++                    | 59% ~35s          
   |++++++++++++++++++++++++++++++                    | 60% ~34s          
   |+++++++++++++++++++++++++++++++                   | 61% ~33s          
   |++++++++++++++++++++++++++++++++                  | 62% ~32s          
   |++++++++++++++++++++++++++++++++                  | 63% ~31s          
   |+++++++++++++++++++++++++++++++++                 | 64% ~31s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~30s          
   |++++++++++++++++++++++++++++++++++                | 67% ~29s          
   |++++++++++++++++++++++++++++++++++                | 68% ~28s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~27s          
   |+++++++++++++++++++++++++++++++++++               | 70% ~26s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~25s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~24s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~23s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~22s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~21s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~20s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~19s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~18s          
   |++++++++++++++++++++++++++++++++++++++++         | 80% ~17s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~17s          
   |++++++++++++++++++++++++++++++++++++++++++        | 82% ~16s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~15s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 84% ~14s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~13s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~12s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~11s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~10s          
   |+++++++++++++++++++++++++++++++++++++++++++++    | 90% ~09s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~08s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 92% ~07s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~06s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 94% ~05s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~04s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 01m 27s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~01m 11s      
   |++                                                | 2 % ~01m 12s      
   |++                                                | 3 % ~01m 11s      
   |+++                                               | 4 % ~01m 12s      
   |+++                                               | 5 % ~01m 12s      
   |++++                                              | 6 % ~01m 12s      
   |++++                                              | 7 % ~01m 11s      
   |+++++                                             | 8 % ~01m 10s      
   |+++++                                             | 9 % ~01m 09s      
   |++++++                                            | 10% ~01m 08s      
   |++++++                                            | 11% ~01m 08s      
   |+++++++                                           | 12% ~01m 07s      
   |+++++++                                           | 13% ~01m 06s      
   |++++++++                                          | 14% ~01m 05s      
   |++++++++                                          | 15% ~01m 04s      
   |+++++++++                                         | 16% ~01m 04s      
   |+++++++++                                         | 17% ~01m 03s      
   |++++++++++                                        | 18% ~01m 02s      
   |++++++++++                                        | 19% ~01m 01s      
   |+++++++++++                                       | 20% ~01m 01s      
   |+++++++++++                                       | 21% ~60s          
   |++++++++++++                                      | 22% ~59s          
   |++++++++++++                                      | 23% ~58s          
   |+++++++++++++                                     | 24% ~58s          
   |+++++++++++++                                     | 25% ~57s          
   |++++++++++++++                                    | 26% ~56s          
   |++++++++++++++                                    | 27% ~55s          
   |+++++++++++++++                                   | 28% ~55s          
   |+++++++++++++++                                   | 29% ~54s          
   |++++++++++++++++                                  | 30% ~54s          
   |++++++++++++++++                                  | 31% ~53s          
   |+++++++++++++++++                                 | 32% ~52s          
   |+++++++++++++++++                                 | 33% ~52s          
   |++++++++++++++++++                                | 34% ~51s          
   |++++++++++++++++++                                | 35% ~50s          
   |+++++++++++++++++++                               | 36% ~49s          
   |+++++++++++++++++++                               | 37% ~48s          
   |++++++++++++++++++++                              | 38% ~48s          
   |++++++++++++++++++++                              | 39% ~47s          
   |+++++++++++++++++++++                             | 40% ~46s          
   |+++++++++++++++++++++                             | 41% ~45s          
   |++++++++++++++++++++++                            | 42% ~44s          
   |++++++++++++++++++++++                            | 43% ~44s          
   |+++++++++++++++++++++++                           | 44% ~43s          
   |+++++++++++++++++++++++                           | 45% ~42s          
   |++++++++++++++++++++++++                          | 46% ~41s          
   |++++++++++++++++++++++++                          | 47% ~40s          
   |+++++++++++++++++++++++++                         | 48% ~39s          
   |+++++++++++++++++++++++++                         | 49% ~39s          
   |++++++++++++++++++++++++++                        | 51% ~38s          
   |++++++++++++++++++++++++++                        | 52% ~37s          
   |+++++++++++++++++++++++++++                       | 53% ~36s          
   |+++++++++++++++++++++++++++                       | 54% ~35s          
   |++++++++++++++++++++++++++++                      | 55% ~35s          
   |++++++++++++++++++++++++++++                      | 56% ~34s          
   |+++++++++++++++++++++++++++++                     | 57% ~33s          
   |+++++++++++++++++++++++++++++                     | 58% ~32s          
   |++++++++++++++++++++++++++++++                    | 59% ~32s          
   |++++++++++++++++++++++++++++++                    | 60% ~31s          
   |+++++++++++++++++++++++++++++++                   | 61% ~30s          
   |+++++++++++++++++++++++++++++++                   | 62% ~29s          
   |++++++++++++++++++++++++++++++++                  | 63% ~28s          
   |++++++++++++++++++++++++++++++++                  | 64% ~28s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~27s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~26s          
   |++++++++++++++++++++++++++++++++++                | 67% ~25s          
   |++++++++++++++++++++++++++++++++++                | 68% ~25s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~24s          
   |+++++++++++++++++++++++++++++++++++               | 70% ~23s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~22s          
   |++++++++++++++++++++++++++++++++++++              | 72% ~21s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~21s          
   |+++++++++++++++++++++++++++++++++++++             | 74% ~20s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~19s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~18s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~18s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~17s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~16s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~15s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~15s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~14s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~13s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~12s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~12s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~11s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~10s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~09s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~08s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~07s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~06s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~05s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~05s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~04s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 01m 16s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~03m 49s      
   |++                                                | 2 % ~03m 41s      
   |++                                                | 3 % ~03m 38s      
   |+++                                               | 4 % ~03m 30s      
   |+++                                               | 5 % ~03m 26s      
   |++++                                              | 6 % ~03m 22s      
   |++++                                              | 8 % ~03m 18s      
   |+++++                                             | 9 % ~03m 18s      
   |+++++                                             | 10% ~03m 15s      
   |++++++                                            | 11% ~03m 13s      
   |++++++                                            | 12% ~03m 11s      
   |+++++++                                           | 13% ~03m 08s      
   |+++++++                                           | 14% ~03m 05s      
   |++++++++                                          | 15% ~03m 02s      
   |+++++++++                                         | 16% ~02m 59s      
   |+++++++++                                         | 17% ~02m 57s      
   |++++++++++                                        | 18% ~02m 54s      
   |++++++++++                                        | 19% ~02m 52s      
   |+++++++++++                                       | 20% ~02m 49s      
   |+++++++++++                                       | 22% ~02m 46s      
   |++++++++++++                                      | 23% ~02m 44s      
   |++++++++++++                                      | 24% ~02m 41s      
   |+++++++++++++                                     | 25% ~02m 39s      
   |+++++++++++++                                     | 26% ~02m 36s      
   |++++++++++++++                                    | 27% ~02m 35s      
   |++++++++++++++                                    | 28% ~02m 32s      
   |+++++++++++++++                                   | 29% ~02m 30s      
   |++++++++++++++++                                  | 30% ~02m 28s      
   |++++++++++++++++                                  | 31% ~02m 26s      
   |+++++++++++++++++                                 | 32% ~02m 24s      
   |+++++++++++++++++                                 | 33% ~02m 21s      
   |++++++++++++++++++                                | 34% ~02m 19s      
   |++++++++++++++++++                                | 35% ~02m 16s      
   |+++++++++++++++++++                               | 37% ~02m 14s      
   |+++++++++++++++++++                               | 38% ~02m 12s      
   |++++++++++++++++++++                              | 39% ~02m 09s      
   |++++++++++++++++++++                              | 40% ~02m 07s      
   |+++++++++++++++++++++                             | 41% ~02m 05s      
   |+++++++++++++++++++++                             | 42% ~02m 03s      
   |++++++++++++++++++++++                            | 43% ~02m 00s      
   |+++++++++++++++++++++++                           | 44% ~01m 58s      
   |+++++++++++++++++++++++                           | 45% ~01m 56s      
   |++++++++++++++++++++++++                          | 46% ~01m 53s      
   |++++++++++++++++++++++++                          | 47% ~01m 51s      
   |+++++++++++++++++++++++++                         | 48% ~01m 49s      
   |+++++++++++++++++++++++++                         | 49% ~01m 46s      
   |++++++++++++++++++++++++++                        | 51% ~01m 44s      
   |++++++++++++++++++++++++++                        | 52% ~01m 42s      
   |+++++++++++++++++++++++++++                       | 53% ~01m 39s      
   |+++++++++++++++++++++++++++                       | 54% ~01m 37s      
   |++++++++++++++++++++++++++++                      | 55% ~01m 35s      
   |++++++++++++++++++++++++++++                      | 56% ~01m 32s      
   |+++++++++++++++++++++++++++++                     | 57% ~01m 31s      
   |++++++++++++++++++++++++++++++                    | 58% ~01m 29s      
   |++++++++++++++++++++++++++++++                    | 59% ~01m 26s      
   |+++++++++++++++++++++++++++++++                   | 60% ~01m 24s      
   |+++++++++++++++++++++++++++++++                   | 61% ~01m 22s      
   |++++++++++++++++++++++++++++++++                  | 62% ~01m 19s      
   |++++++++++++++++++++++++++++++++                  | 63% ~01m 17s      
   |+++++++++++++++++++++++++++++++++                 | 65% ~01m 15s      
   |+++++++++++++++++++++++++++++++++                 | 66% ~01m 13s      
   |++++++++++++++++++++++++++++++++++                | 67% ~01m 10s      
   |++++++++++++++++++++++++++++++++++                | 68% ~01m 08s      
   |+++++++++++++++++++++++++++++++++++               | 69% ~01m 06s      
   |+++++++++++++++++++++++++++++++++++               | 70% ~01m 04s      
   |++++++++++++++++++++++++++++++++++++              | 71% ~01m 01s      
   |+++++++++++++++++++++++++++++++++++++             | 72% ~59s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~57s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~54s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~52s          
   |+++++++++++++++++++++++++++++++++++++++           | 76% ~50s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~48s          
   |++++++++++++++++++++++++++++++++++++++++          | 78% ~45s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~43s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~41s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~39s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~37s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~35s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~33s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~30s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~28s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~26s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~23s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 90% ~21s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~19s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 92% ~16s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~14s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~12s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~09s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~07s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~05s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 03m 33s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~06m 60s      
   |+                                                 | 2 % ~06m 44s      
   |++                                                | 3 % ~06m 36s      
   |++                                                | 4 % ~06m 34s      
   |+++                                               | 5 % ~06m 29s      
   |+++                                               | 6 % ~06m 22s      
   |++++                                              | 7 % ~06m 21s      
   |++++                                              | 8 % ~06m 16s      
   |+++++                                             | 9 % ~06m 10s      
   |+++++                                             | 10% ~06m 04s      
   |++++++                                            | 11% ~05m 59s      
   |++++++                                            | 12% ~05m 53s      
   |+++++++                                           | 13% ~05m 48s      
   |+++++++                                           | 14% ~05m 44s      
   |++++++++                                          | 15% ~05m 39s      
   |++++++++                                          | 16% ~05m 35s      
   |+++++++++                                         | 17% ~05m 30s      
   |+++++++++                                         | 18% ~05m 26s      
   |++++++++++                                        | 19% ~05m 22s      
   |++++++++++                                        | 20% ~05m 19s      
   |+++++++++++                                       | 21% ~05m 15s      
   |+++++++++++                                       | 22% ~05m 12s      
   |++++++++++++                                      | 23% ~05m 11s      
   |++++++++++++                                      | 24% ~05m 07s      
   |+++++++++++++                                     | 25% ~05m 03s      
   |+++++++++++++                                     | 26% ~04m 60s      
   |++++++++++++++                                    | 27% ~04m 56s      
   |++++++++++++++                                    | 28% ~04m 52s      
   |+++++++++++++++                                   | 29% ~04m 48s      
   |+++++++++++++++                                   | 30% ~04m 43s      
   |++++++++++++++++                                  | 31% ~04m 38s      
   |++++++++++++++++                                  | 32% ~04m 34s      
   |+++++++++++++++++                                 | 33% ~04m 29s      
   |+++++++++++++++++                                | 34% ~04m 25s      
   |++++++++++++++++++                                | 35% ~04m 21s      
   |++++++++++++++++++                                | 36% ~04m 17s      
   |+++++++++++++++++++                               | 37% ~04m 13s      
   |+++++++++++++++++++                               | 38% ~04m 08s      
   |++++++++++++++++++++                              | 39% ~04m 04s      
   |++++++++++++++++++++                              | 40% ~03m 60s      
   |+++++++++++++++++++++                             | 41% ~03m 57s      
   |+++++++++++++++++++++                             | 42% ~03m 53s      
   |++++++++++++++++++++++                            | 43% ~03m 48s      
   |++++++++++++++++++++++                            | 44% ~03m 44s      
   |+++++++++++++++++++++++                           | 45% ~03m 40s      
   |+++++++++++++++++++++++                           | 46% ~03m 36s      
   |++++++++++++++++++++++++                          | 47% ~03m 32s      
   |++++++++++++++++++++++++                          | 48% ~03m 28s      
   |+++++++++++++++++++++++++                         | 49% ~03m 24s      
   |+++++++++++++++++++++++++                         | 50% ~03m 19s      
   |++++++++++++++++++++++++++                        | 51% ~03m 15s      
   |++++++++++++++++++++++++++                        | 52% ~03m 11s      
   |+++++++++++++++++++++++++++                       | 53% ~03m 07s      
   |+++++++++++++++++++++++++++                       | 54% ~03m 03s      
   |++++++++++++++++++++++++++++                      | 55% ~02m 59s      
   |++++++++++++++++++++++++++++                     | 56% ~02m 55s      
   |+++++++++++++++++++++++++++++                     | 57% ~02m 51s      
   |+++++++++++++++++++++++++++++                     | 58% ~02m 47s      
   |++++++++++++++++++++++++++++++                    | 59% ~02m 43s      
   |++++++++++++++++++++++++++++++                    | 60% ~02m 39s      
   |+++++++++++++++++++++++++++++++                   | 61% ~02m 35s      
   |+++++++++++++++++++++++++++++++                   | 62% ~02m 31s      
   |++++++++++++++++++++++++++++++++                  | 63% ~02m 27s      
   |++++++++++++++++++++++++++++++++                  | 64% ~02m 23s      
   |+++++++++++++++++++++++++++++++++                 | 65% ~02m 19s      
   |+++++++++++++++++++++++++++++++++                 | 66% ~02m 15s      
   |++++++++++++++++++++++++++++++++++                | 67% ~02m 11s      
   |++++++++++++++++++++++++++++++++++               | 68% ~02m 07s      
   |+++++++++++++++++++++++++++++++++++               | 69% ~02m 03s      
   |+++++++++++++++++++++++++++++++++++               | 70% ~01m 60s      
   |++++++++++++++++++++++++++++++++++++              | 71% ~01m 56s      
   |++++++++++++++++++++++++++++++++++++              | 72% ~01m 52s      
   |+++++++++++++++++++++++++++++++++++++             | 73% ~01m 47s      
   |+++++++++++++++++++++++++++++++++++++             | 74% ~01m 43s      
   |++++++++++++++++++++++++++++++++++++++            | 75% ~01m 39s      
   |++++++++++++++++++++++++++++++++++++++            | 76% ~01m 35s      
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~01m 31s      
   |+++++++++++++++++++++++++++++++++++++++          | 78% ~01m 27s      
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~01m 23s      
   |++++++++++++++++++++++++++++++++++++++++         | 80% ~01m 19s      
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~01m 15s      
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~01m 11s      
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~01m 07s      
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~01m 03s      
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~59s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~55s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~51s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~48s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~44s          
   |+++++++++++++++++++++++++++++++++++++++++++++    | 90% ~40s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~36s          
   |++++++++++++++++++++++++++++++++++++++++++++++   | 92% ~32s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~28s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~24s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~20s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~16s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~12s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~04s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 06m 34s

Display the top markers you computed above.

tiss.markers %>% group_by(cluster) %>% top_n(20, avg_logFC)

Generate an expression heatmap for given cells and genes. In this case, we are plotting the top 20 markers (or all markers if less than 20) for each cluster.

Assigning cell type identity to clusters

At a coarse level, we can use canonical markers to match the unbiased clustering to known cell types: Cluster 0: basal cell of epidermis (CL:0002187) Cluster 1: differentiated keratinocytes (CL:0000312) Cluster 2: proliferating basal cell of epidermis (CL:0002187) Clutser 3: suprabasal differentiating keratinocytes (CL:0000312) Cluster 4: basal cell of epidermis (CL:0002187) Cluster 5: suprabasal differentiated keratinocytes (CL:0000312) Cluster 6: basal cell of epidermis (CL:0002187) Cluster 7: basal cell of epidermis (CL:0002187) Clutser 8: basal cell of epidermis (CL:0002187) Cluster 9: filiform differentiated keratinocytes (CL:0000312) Cluster 10: Langerhans cells (CL_0000453)

# stash current cluster IDs
tiss <- StashIdent(object = tiss, save.name = "cluster.ids")
# enumerate current cluster IDs and the labels for them
cluster.ids <- c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
free_cell_ontology_id <- c("basal_cells", "differentiated", "proliferating","suprabasal_differentiating", "basal_cells","suprabasal_differentiated", "basal_cells", "basal_cells", "basal_cells", "filiform_differentiated", "Langerhans cells")
cell_ontology_class <- c("CL:0002187", "CL:0000312", "CL:0002187", "CL:0000312", "CL:0002187", "CL:0000312", "CL:0002187", "CL:0002187", "CL:0002187", "CL:0000312", 'CL_0000453')
cell_ontology_id <- c("CL:0002187", "CL:0000312", "CL:0002187", "CL:0000312", "CL:0002187", "CL:0000312", "CL:0002187", "CL:0002187", "CL:0002187", "CL:0000312s", 'CL_0000453')
#subcell_ontology_class = c("differentiating", "differentiating", "differentiating", "proliferating", "differentiating", "differentiating", "differentiating", "differentiating", "Filiform", NA)
cell_ontology_class.subcell_ontology_class = paste0(cell_ontology_class,': ', free_cell_ontology_id)
tiss@meta.data[,'cell_ontology_class'] <- plyr::mapvalues(x = tiss@ident, from = cluster.ids, to = cell_ontology_class)
tiss@meta.data[,'cell_ontology_id'] <- plyr::mapvalues(x = tiss@ident, from = cluster.ids, to = cell_ontology_id)
tiss@meta.data[tiss@cell.names,'cell_ontology_class'] <- as.character(tiss@meta.data$cell_ontology_class)
tiss@meta.data[tiss@cell.names,'cell_ontology_id'] <- as.character(tiss@meta.data$cell_ontology_id)
tiss@meta.data[,'subcell_ontology_class'] <- plyr::mapvalues(x = tiss@meta.data$cluster.ids, from = cluster.ids, to = free_cell_ontology_id)
tiss@meta.data[,'cell_ontology_class.subcell_ontology_class'] <- plyr::mapvalues(x = tiss@meta.data$cluster.ids, from = cluster.ids, to = cell_ontology_class.subcell_ontology_class)
TSNEPlot(object = tiss, do.label = TRUE, pt.size = 0.5, group.by='cell_ontology_class')

TSNEPlot(object = tiss, do.label = TRUE, pt.size = 0.5, group.by='cell_ontology_class.subcell_ontology_class')

Checking for batch effects

Color by metadata, like plate barcode, to check for batch effects.

TSNEPlot(object = tiss, do.return = TRUE, group.by = "channel")

TSNEPlot(object = tiss, do.return = TRUE, group.by = "mouse.sex")

Print a table showing the count of cells in each identity category from each plate.

table(as.character(tiss@ident), as.character(tiss@meta.data$channel))
    
     10X_P4_0 10X_P4_1 10X_P7_10
  0       676      677       300
  1       640      316       421
  10       16        9        12
  2       206      233       414
  3       383      258       139
  4       292      275       131
  5       232      249       108
  6       155      224       110
  7       259      137        75
  8       162       33       194
  9        80       77        45

Save the Robject for later

When you save the annotated tissue, please give it a name.

filename = here('00_data_ingest', '04_tissue_robj_generated', 
          paste0("droplet", tissue_of_interest, "_seurat_tiss.Robj"))
print(filename)
[1] "/Users/Jintonic/Documents/GitHub/tabula-muris/00_data_ingest/04_tissue_robj_generated/dropletTongue_seurat_tiss.Robj"
save(tiss, file=filename)
# To reload a saved object
# filename = here('00_data_ingest', '04_tissue_robj_generated', 
#                      paste0("facs", tissue_of_interest, "_seurat_tiss.Robj"))
# load(file=filename)

Export the final metadata

So that Biohub can easily combine all your cell_ontology_classs, please export them as a simple csv.

head(tiss@meta.data)
filename = here('00_data_ingest', '03_tissue_annotation_csv', 
          paste0(tissue_of_interest, "_droplet_cell_ontology_class.csv"))
write.csv(tiss@meta.data[,c('channel','cell_ontology_class','cell_ontology_class.subcell_ontology_class')], file=filename)
LS0tCiB0aXRsZTogIlRvbmd1ZSBEcm9wbGV0IE5vdGVib29rIgogb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKRW50ZXIgdGhlIGRpcmVjdG9yeSBvZiB0aGUgbWFjYSBmb2xkZXIgb24geW91ciBkcml2ZSBhbmQgdGhlIG5hbWUgb2YgdGhlIHRpc3N1ZSB5b3Ugd2FudCB0byBhbmFseXplLgoKYGBge3J9CnRpc3N1ZV9vZl9pbnRlcmVzdCA9ICJUb25ndWUiCmBgYAoKTG9hZCB0aGUgcmVxdWlzaXRlIHBhY2thZ2VzIGFuZCBzb21lIGFkZGl0aW9uYWwgaGVscGVyIGZ1bmN0aW9ucy4KCmBgYHtyfQpsaWJyYXJ5KGhlcmUpCmxpYnJhcnkodXNlZnVsKQpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShkcGx5cikKbGlicmFyeShNYXRyaXgpCmxpYnJhcnkob250b2xvZ3lJbmRleCkKY2VsbF9vbnRvbG9neSA9IGdldF9vbnRvbG9neSgnaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL29ib3BoZW5vdHlwZS9jZWxsLW9udG9sb2d5L21hc3Rlci9jbC1iYXNpYy5vYm8nLCBleHRyYWN0X3RhZ3M9J2V2ZXJ5dGhpbmcnKQoKdmFsaWRhdGVfY2VsbF9vbnRvbG9neSA9IGZ1bmN0aW9uKGNlbGxfb250b2xvZ3lfY2xhc3MpewogIGluX2NlbGxfb250b2xvZ3kgPSBzYXBwbHkoY2VsbF9vbnRvbG9neV9jbGFzcywgZnVuY3Rpb24oeCkgaXMuZWxlbWVudCh4LCBjZWxsX29udG9sb2d5JG5hbWUpKQogIGlmICghYWxsKGluX2NlbGxfb250b2xvZ3kpKSB7CiAgICBtZXNzYWdlID0gcGFzdGUwKCciJywgY2VsbF9vbnRvbG9neV9jbGFzc1shaW5fY2VsbF9vbnRvbG9neV0sICciIGlzIG5vdCBpbiB0aGUgY2VsbCBvbnRvbG9neQonKQogICAgc3RvcChtZXNzYWdlKQogIH0KfQpjb252ZXJ0X3RvX2NlbGxfb250b2xvZ3lfaWQgPSBmdW5jdGlvbihjZWxsX29udG9sb2d5X2NsYXNzKXsKICByZXR1cm4oc2FwcGx5KGNlbGxfb250b2xvZ3lfY2xhc3MsIGZ1bmN0aW9uKHgpIGFzLnZlY3RvcihjZWxsX29udG9sb2d5JGlkW2NlbGxfb250b2xvZ3kkbmFtZSA9PSB4XSlbMV0pKQp9CnNhdmVfZGlyID0gaGVyZSgnMDBfZGF0YV9pbmdlc3QnLCAnMDRfdGlzc3VlX3JvYmpfZ2VuZXJhdGVkJykKYGBgCgoKCmBgYHtyfQojIHJlYWQgdGhlIG1ldGFkYXRhIHRvIGdldCB0aGUgcGxhdGVzIHdlIHdhbnQKZHJvcGxldF9tZXRhZGF0YV9maWxlbmFtZSA9IGhlcmUoJzAwX2RhdGFfaW5nZXN0JywgJzAxX2Ryb3BsZXRfcmF3X2RhdGEnLCAnbWV0YWRhdGFfZHJvcGxldC5jc3YnKQoKZHJvcGxldF9tZXRhZGF0YSA8LSByZWFkLmNzdihkcm9wbGV0X21ldGFkYXRhX2ZpbGVuYW1lLCBzZXA9IiwiLCBoZWFkZXIgPSBUUlVFKQpjb2xuYW1lcyhkcm9wbGV0X21ldGFkYXRhKVsxXSA8LSAiY2hhbm5lbCIKZHJvcGxldF9tZXRhZGF0YQpgYGAKClN1YnNldCB0aGUgbWV0YWRhdGEgb24gdGhlIHRpc3N1ZS4KCmBgYHtyfQp0aXNzdWVfbWV0YWRhdGEgPSBmaWx0ZXIoZHJvcGxldF9tZXRhZGF0YSwgdGlzc3VlID09IHRpc3N1ZV9vZl9pbnRlcmVzdClbLGMoJ2NoYW5uZWwnLCd0aXNzdWUnLCdzdWJ0aXNzdWUnLCdtb3VzZS5zZXgnKV0KdGlzc3VlX21ldGFkYXRhCmBgYAoKClVzZSBvbmx5IHRoZSBtZXRhZGF0YSByb3dzIGNvcnJlc3BvbmRpbmcgdG8gQmxhZGRlciBwbGF0ZXMuIE1ha2UgYSBwbGF0ZSBiYXJjb2RlIGRhdGFmcmFtZSB0byAiZXhwYW5kIiB0aGUgcGVyLXBsYXRlIG1ldGFkYXRhIHRvIGJlIHBlci1jZWxsLgoKYGBge3J9CiMgTG9hZCB0aGUgZ2VuZSBuYW1lcyBhbmQgc2V0IHRoZSBtZXRhZGF0YSBjb2x1bW5zIGJ5IG9wZW5pbmcgdGhlIGZpcnN0IGZpbGUKCnN1YmZvbGRlciA9IHBhc3RlMCh0aXNzdWVfb2ZfaW50ZXJlc3QsICctJywgdGlzc3VlX21ldGFkYXRhJGNoYW5uZWxbMV0pCnJhdy5kYXRhIDwtIFJlYWQxMFgoZGF0YS5kaXIgPSBoZXJlKCcwMF9kYXRhX2luZ2VzdCcsICcwMV9kcm9wbGV0X3Jhd19kYXRhJywgJ2Ryb3BsZXQnLCBzdWJmb2xkZXIpKQpjb2xuYW1lcyhyYXcuZGF0YSkgPC0gbGFwcGx5KGNvbG5hbWVzKHJhdy5kYXRhKSwgZnVuY3Rpb24oeCkgcGFzdGUwKHRpc3N1ZV9tZXRhZGF0YSRjaGFubmVsWzFdLCAnXycsIHgpKQptZXRhLmRhdGEgPSBkYXRhLmZyYW1lKHJvdy5uYW1lcyA9IGNvbG5hbWVzKHJhdy5kYXRhKSkKbWV0YS5kYXRhWydjaGFubmVsJ10gPSB0aXNzdWVfbWV0YWRhdGEkY2hhbm5lbFsxXQoKaWYgKGxlbmd0aCh0aXNzdWVfbWV0YWRhdGEkY2hhbm5lbCkgPiAxKXsKICAjIFNvbWUgdGlzc3VlcywgbGlrZSBUaHltdXMgYW5kIEhlYXJ0IGhhZCBvbmx5IG9uZSBjaGFubmVsCiAgZm9yKGkgaW4gMjpucm93KHRpc3N1ZV9tZXRhZGF0YSkpewogICAgc3ViZm9sZGVyID0gcGFzdGUwKHRpc3N1ZV9vZl9pbnRlcmVzdCwgJy0nLCB0aXNzdWVfbWV0YWRhdGEkY2hhbm5lbFtpXSkKICAgIG5ldy5kYXRhIDwtIFJlYWQxMFgoZGF0YS5kaXIgPSBoZXJlKCcwMF9kYXRhX2luZ2VzdCcsICcwMV9kcm9wbGV0X3Jhd19kYXRhJywgJ2Ryb3BsZXQnLCBzdWJmb2xkZXIpKQogICAgY29sbmFtZXMobmV3LmRhdGEpIDwtIGxhcHBseShjb2xuYW1lcyhuZXcuZGF0YSksIGZ1bmN0aW9uKHgpIHBhc3RlMCh0aXNzdWVfbWV0YWRhdGEkY2hhbm5lbFtpXSwgJ18nLCB4KSkKICAgIAogICAgbmV3Lm1ldGFkYXRhID0gZGF0YS5mcmFtZShyb3cubmFtZXMgPSBjb2xuYW1lcyhuZXcuZGF0YSkpCiAgICBuZXcubWV0YWRhdGFbJ2NoYW5uZWwnXSA9IHRpc3N1ZV9tZXRhZGF0YSRjaGFubmVsW2ldCiAgICAKICAgIHJhdy5kYXRhID0gY2JpbmQocmF3LmRhdGEsIG5ldy5kYXRhKQogICAgbWV0YS5kYXRhID0gcmJpbmQobWV0YS5kYXRhLCBuZXcubWV0YWRhdGEpCiAgfQp9CgpybmFtZXMgPSByb3cubmFtZXMobWV0YS5kYXRhKQptZXRhLmRhdGEgPC0gbWVyZ2UobWV0YS5kYXRhLCB0aXNzdWVfbWV0YWRhdGEsIHNvcnQgPSBGKQpyb3cubmFtZXMobWV0YS5kYXRhKSA8LSBybmFtZXMKZGltKHJhdy5kYXRhKQpjb3JuZXIocmF3LmRhdGEpCmhlYWQobWV0YS5kYXRhKQpgYGAKUHJvY2VzcyB0aGUgcmF3IGRhdGEgYW5kIGxvYWQgaXQgaW50byB0aGUgU2V1cmF0IG9iamVjdC4KCmBgYHtyfQojIEZpbmQgRVJDQydzLCBjb21wdXRlIHRoZSBwZXJjZW50IEVSQ0MsIGFuZCBkcm9wIHRoZW0gZnJvbSB0aGUgcmF3IGRhdGEuCmVyY2NzIDwtIGdyZXAocGF0dGVybiA9ICJeRVJDQy0iLCB4ID0gcm93bmFtZXMoeCA9IHJhdy5kYXRhKSwgdmFsdWUgPSBUUlVFKQpwZXJjZW50LmVyY2MgPC0gTWF0cml4Ojpjb2xTdW1zKHJhdy5kYXRhW2VyY2NzLCBdKS9NYXRyaXg6OmNvbFN1bXMocmF3LmRhdGEpCmVyY2MuaW5kZXggPC0gZ3JlcChwYXR0ZXJuID0gIl5FUkNDLSIsIHggPSByb3duYW1lcyh4ID0gcmF3LmRhdGEpLCB2YWx1ZSA9IEZBTFNFKQpyYXcuZGF0YSA8LSByYXcuZGF0YVstZXJjYy5pbmRleCxdCgojIENyZWF0ZSB0aGUgU2V1cmF0IG9iamVjdCB3aXRoIGFsbCB0aGUgZGF0YQp0aXNzIDwtIENyZWF0ZVNldXJhdE9iamVjdChyYXcuZGF0YSA9IHJhdy5kYXRhLCBwcm9qZWN0ID0gdGlzc3VlX29mX2ludGVyZXN0LCAKICAgICAgICAgICAgICAgICAgICBtaW4uY2VsbHMgPSA1LCBtaW4uZ2VuZXMgPSA1KQoKdGlzcyA8LSBBZGRNZXRhRGF0YShvYmplY3QgPSB0aXNzLCBtZXRhLmRhdGEpCnRpc3MgPC0gQWRkTWV0YURhdGEob2JqZWN0ID0gdGlzcywgcGVyY2VudC5lcmNjLCBjb2wubmFtZSA9ICJwZXJjZW50LmVyY2MiKQojIENoYW5nZSBkZWZhdWx0IG5hbWUgZm9yIHN1bXMgb2YgY291bnRzIGZyb20gblVNSSB0byBuUmVhZHMKIyBjb2xuYW1lcyh0aXNzQG1ldGEuZGF0YSlbY29sbmFtZXModGlzc0BtZXRhLmRhdGEpID09ICduVU1JJ10gPC0gJ25SZWFkcycKCiMgQ3JlYXRlIG1ldGFkYXRhIGNvbHVtbnMgZm9yIGNlbGxfb250b2xvZ3lfY2xhc3NzIGFuZCBzdWJjZWxsX29udG9sb2d5X2NsYXNzcwp0aXNzQG1ldGEuZGF0YVssJ2NlbGxfb250b2xvZ3lfY2xhc3MnXSA8LSBOQQp0aXNzQG1ldGEuZGF0YVssJ3N1YmNlbGxfb250b2xvZ3lfY2xhc3MnXSA8LSBOQQpgYGAKCgpDYWxjdWxhdGUgcGVyY2VudCByaWJvc29tYWwgZ2VuZXMuCgpgYGB7cn0Kcmliby5nZW5lcyA8LSBncmVwKHBhdHRlcm4gPSAiXlJwW3NsXVtbOmRpZ2l0Ol1dIiwgeCA9IHJvd25hbWVzKHggPSB0aXNzQGRhdGEpLCB2YWx1ZSA9IFRSVUUpCnBlcmNlbnQucmlibyA8LSBNYXRyaXg6OmNvbFN1bXModGlzc0ByYXcuZGF0YVtyaWJvLmdlbmVzLCBdKS9NYXRyaXg6OmNvbFN1bXModGlzc0ByYXcuZGF0YSkKdGlzcyA8LSBBZGRNZXRhRGF0YShvYmplY3QgPSB0aXNzLCBtZXRhZGF0YSA9IHBlcmNlbnQucmlibywgY29sLm5hbWUgPSAicGVyY2VudC5yaWJvIikKYGBgCgpBIHNhbml0eSBjaGVjazogZ2VuZXMgcGVyIGNlbGwgdnMgcmVhZHMgcGVyIGNlbGwuCgpgYGB7cn0KR2VuZVBsb3Qob2JqZWN0ID0gdGlzcywgZ2VuZTEgPSAiblVNSSIsIGdlbmUyID0gIm5HZW5lIiwgdXNlLnJhdz1UKQpgYGAKCkZpbHRlciBvdXQgY2VsbHMgd2l0aCBmZXcgcmVhZHMgYW5kIGZldyBnZW5lcy4KCmBgYHtyfQp0aXNzIDwtIEZpbHRlckNlbGxzKG9iamVjdCA9IHRpc3MsIHN1YnNldC5uYW1lcyA9IGMoIm5HZW5lIiwgIm5VTUkiKSwgCiAgICBsb3cudGhyZXNob2xkcyA9IGMoNTAwLCAxMDAwKSwgaGlnaC50aHJlc2hvbGRzID0gYygyNTAwMCwgNTAwMDAwMCkpCmBgYAoKCk5vcm1hbGl6ZSB0aGUgZGF0YSwgdGhlbiByZWdyZXNzIG91dCBjb3JyZWxhdGlvbiB3aXRoIHRvdGFsIHJlYWRzCmBgYHtyfQp0aXNzIDwtIE5vcm1hbGl6ZURhdGEob2JqZWN0ID0gdGlzcywgc2NhbGUuZmFjdG9yID0gMWU0KQp0aXNzIDwtIFNjYWxlRGF0YShvYmplY3QgPSB0aXNzKQp0aXNzIDwtIEZpbmRWYXJpYWJsZUdlbmVzKG9iamVjdCA9IHRpc3MsIGRvLnBsb3QgPSBUUlVFLCB4LmhpZ2guY3V0b2ZmID0gSW5mLCB5LmN1dG9mZiA9IDAuNSkKYGBgCgoKUnVuIFByaW5jaXBhbCBDb21wb25lbnQgQW5hbHlzaXMuCmBgYHtyfQp0aXNzIDwtIFJ1blBDQShvYmplY3QgPSB0aXNzLCBkby5wcmludCA9IEZBTFNFKQp0aXNzIDwtIFByb2plY3RQQ0Eob2JqZWN0ID0gdGlzcywgZG8ucHJpbnQgPSBGQUxTRSkKYGBgCgpgYGB7ciwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD0xNiwgZmlnLndpZHRoPTh9CiNQQ0hlYXRtYXAob2JqZWN0ID0gdGlzcywgcGMudXNlID0gMTozLCBjZWxscy51c2UgPSA1MDAsIGRvLmJhbGFuY2VkID0gVFJVRSwgbGFiZWwuY29sdW1ucyA9IEZBTFNFLCBudW0uZ2VuZXMgPSA4KQpQQ0hlYXRtYXAob2JqZWN0ID0gdGlzcywgcGMudXNlID0gMToxMCwgY2VsbHMudXNlID0gNTAwLCBkby5iYWxhbmNlZCA9IFRSVUUsIAogICAgbGFiZWwuY29sdW1ucyA9IEZBTFNFLCB1c2UuZnVsbCA9IEZBTFNFKQpgYGAKCkxhdGVyIG9uIChpbiBGaW5kQ2x1c3RlcnMgYW5kIFRTTkUpIHlvdSB3aWxsIHBpY2sgYSBudW1iZXIgb2YgcHJpbmNpcGFsIGNvbXBvbmVudHMgdG8gdXNlLiBUaGlzIGhhcyB0aGUgZWZmZWN0IG9mIGtlZXBpbmcgdGhlIG1ham9yIGRpcmVjdGlvbnMgb2YgdmFyaWF0aW9uIGluIHRoZSBkYXRhIGFuZCwgaWRlYWxseSwgc3VwcmVzc2luZyBub2lzZS4gVGhlcmUgaXMgbm8gY29ycmVjdCBhbnN3ZXIgdG8gdGhlIG51bWJlciB0byB1c2UsIGJ1dCBhIGRlY2VudCBydWxlIG9mIHRodW1iIGlzIHRvIGdvIHVudGlsIHRoZSBwbG90IHBsYXRlYXVzLgoKYGBge3J9ClBDRWxib3dQbG90KG9iamVjdCA9IHRpc3MpCmBgYAoKQ2hvb3NlIHRoZSBudW1iZXIgb2YgcHJpbmNpcGFsIGNvbXBvbmVudHMgdG8gdXNlLgpgYGB7cn0KIyBTZXQgbnVtYmVyIG9mIHByaW5jaXBhbCBjb21wb25lbnRzLiAKbi5wY3MgPSAxNApgYGAKCgpUaGUgY2x1c3RlcmluZyBpcyBwZXJmb3JtZWQgYmFzZWQgb24gYSBuZWFyZXN0IG5laWdoYm9ycyBncmFwaC4gQ2VsbHMgdGhhdCBoYXZlIHNpbWlsYXIgZXhwcmVzc2lvbiB3aWxsIGJlIGpvaW5lZCB0b2dldGhlci4gVGhlIExvdXZhaW4gYWxnb3JpdGhtIGxvb2tzIGZvciBncm91cHMgb2YgY2VsbHMgd2l0aCBoaWdoIG1vZHVsYXJpdHktLW1vcmUgY29ubmVjdGlvbnMgd2l0aGluIHRoZSBncm91cCB0aGFuIGJldHdlZW4gZ3JvdXBzLiBUaGUgcmVzb2x1dGlvbiBwYXJhbWV0ZXIgZGV0ZXJtaW5lcyB0aGUgc2NhbGUuLi5oaWdoZXIgcmVzb2x1dGlvbiB3aWxsIGdpdmUgbW9yZSBjbHVzdGVycywgbG93ZXIgcmVzb2x1dGlvbiB3aWxsIGdpdmUgZmV3ZXIuCgpGb3IgdGhlIHRvcC1sZXZlbCBjbHVzdGVyaW5nLCBhaW0gdG8gdW5kZXItY2x1c3RlciBpbnN0ZWFkIG9mIG92ZXItY2x1c3Rlci4gSXQgd2lsbCBiZSBlYXN5IHRvIHN1YnNldCBncm91cHMgYW5kIGZ1cnRoZXIgYW5hbHl6ZSB0aGVtIGJlbG93LgoKYGBge3J9CiMgU2V0IHJlc29sdXRpb24gCnJlcy51c2VkIDwtIDAuNQoKdGlzcyA8LSBGaW5kQ2x1c3RlcnMob2JqZWN0ID0gdGlzcywgcmVkdWN0aW9uLnR5cGUgPSAicGNhIiwgZGltcy51c2UgPSAxOm4ucGNzLCAKICAgIHJlc29sdXRpb24gPSByZXMudXNlZCwgcHJpbnQub3V0cHV0ID0gMCwgc2F2ZS5TTk4gPSBUUlVFLCBmb3JjZS5yZWNhbGMgPSBUUlVFKQpgYGAKCgpUbyB2aXN1YWxpemUgCmBgYHtyfQojIElmIGNlbGxzIGFyZSB0b28gc3ByZWFkIG91dCwgeW91IGNhbiByYWlzZSB0aGUgcGVycGxleGl0eS4gSWYgeW91IGhhdmUgZmV3IGNlbGxzLCB0cnkgYSBsb3dlciBwZXJwbGV4aXR5IChidXQgbmV2ZXIgbGVzcyB0aGFuIDEwKS4KdGlzcyA8LSBSdW5UU05FKG9iamVjdCA9IHRpc3MsIGRpbXMudXNlID0gMTpuLnBjcywgc2VlZC51c2UgPSAyMCwgcGVycGxleGl0eT0zNSwgZGltLmVtYmVkID0gMikKVFNORVBsb3Qob2JqZWN0ID0gdGlzcywgZG8ubGFiZWwgPSBULCBwdC5zaXplID0gMS4yLCBsYWJlbC5zaXplID0gNCkKYGBgCgojIFNhdmUgdGhlIFJvYmplY3QgZm9yIGxhdGVyCldoZW4geW91IHNhdmUgdGhlIGFubm90YXRlZCB0aXNzdWUsIHBsZWFzZSBnaXZlIGl0IGEgbmFtZS4KCmBgYHtyfQpmaWxlbmFtZSA9IGhlcmUoJzAwX2RhdGFfaW5nZXN0JywgJzA0X3Rpc3N1ZV9yb2JqX2dlbmVyYXRlZCcsIAoJCSAgcGFzdGUwKCJkcm9wbGV0IiwgdGlzc3VlX29mX2ludGVyZXN0LCAiX3NldXJhdF90aXNzLlJvYmoiKSkKcHJpbnQoZmlsZW5hbWUpCnNhdmUodGlzcywgZmlsZT1maWxlbmFtZSkKYGBgCgpDaGVjayBleHByZXNzaW9uIG9mIGdlbmVzIG9mIGludGVyc2V0LgoKYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9MTYsIGZpZy53aWR0aD0xMH0KZ2VuZXNfdG9fY2hlY2sgPSBjKCdJdGdiNCcsICdJdGdhNicsICdJdGdiMScsICdDZGgzJywgJ1RvcDJhJywgJ010MicsICdLcnQxNScsICdLcnQ1JywgJ0tydDE0JywgJ1Nic24nLCAnS3J0MTAnLCdLbGY0JwosICdLcnQ4NCcsICdLcnQzNicsJ0tydDMzYicsICdIb3hjMTMnLCAnS3J0NCcsICdLcnQxMycsICdGYWJwNScsICdLcnQzMicsICAnS3J0NzgnLCAnVmltJywgJ0hoaXAnLCAnUHRjaDEnLCAnR2xpMScsJ0RzYzEnLCAnRGNuJywgJ1J1bngyJywgJ1NveDInLCAnUGF4OScpCkZlYXR1cmVQbG90KHRpc3MsIGdlbmVzX3RvX2NoZWNrLCBwdC5zaXplID0gMSwgbkNvbCA9IDQpCmBgYAoKRG90cGxvdHMgbGV0IHlvdSBzZWUgdGhlIGludGVuc2l0eSBvZiBleHBwcmVzc2lvbiBhbmQgdGhlIGZyYWN0aW9uIG9mIGNlbGxzIGV4cHJlc3NpbmcgZm9yIGVhY2ggb2YgeW91ciBnZW5lcyBvZiBpbnRlcmVzdC4KCmBgYHtyLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD0yMH0KIyBUbyBjaGFuZ2UgdGhlIHktYXhpcyB0byBzaG93IHJhdyBjb3VudHMsIGFkZCB1c2UucmF3ID0gVC4KRG90UGxvdCh0aXNzLCBnZW5lc190b19jaGVjaywgcGxvdC5sZWdlbmQgPSBUKQpgYGAKCgpgYGB7ciwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD0yMCwgZmlnLndpZHRoPTIwfQojIFRvIGNoYW5nZSB0aGUgeS1heGlzIHRvIHNob3cgcmF3IGNvdW50cywgYWRkIHVzZS5yYXcgPSBULgpWbG5QbG90KHRpc3MsIGdlbmVzX3RvX2NoZWNrLCB5LmxvZyA9IFRSVUUpCmBgYAoKCkhvdyBiaWcgYXJlIHRoZSBjbHVzdGVycz8KYGBge3J9CnRhYmxlKHRpc3NAaWRlbnQpCmBgYAoKYGBge3J9CnRpc3MxPUJ1aWxkQ2x1c3RlclRyZWUodGlzcykKYGBgCgpgYGB7cn0KI2NsdXN0ZXIxLm1hcmtlcnMgPC0gRmluZE1hcmtlcnMob2JqZWN0ID0gdGlzcywgaWRlbnQuMSA9IDEsIG1pbi5wY3QgPSAwLjI1LCBvbmx5LnBvcyA9IFRSVUUsIHRocmVzaC51c2UgPSAwLjI1KQojY2x1c3RlcjIubWFya2VycyA8LSBGaW5kTWFya2VycyhvYmplY3QgPSB0aXNzLCBpZGVudC4xID0gMiwgbWluLnBjdCA9IDAuMjUsIG9ubHkucG9zID0gVFJVRSwgdGhyZXNoLnVzZSA9IDAuMjUpCiNjbHVzdGVyMy5tYXJrZXJzIDwtIEZpbmRNYXJrZXJzKG9iamVjdCA9IHRpc3MsIGlkZW50LjEgPSAzLCBtaW4ucGN0ID0gMC4yNSwgb25seS5wb3MgPSBUUlVFLCB0aHJlc2gudXNlID0gMC4yNSkKI2NsdXN0ZXI0Lm1hcmtlcnMgPC0gRmluZE1hcmtlcnMob2JqZWN0ID0gdGlzcywgaWRlbnQuMSA9IDQsIG1pbi5wY3QgPSAwLjI1LCBvbmx5LnBvcyA9IFRSVUUsIHRocmVzaC51c2UgPSAwLjI1KQojY2x1c3RlcjUubWFya2VycyA8LSBGaW5kTWFya2VycyhvYmplY3QgPSB0aXNzLCBpZGVudC4xID0gNSwgbWluLnBjdCA9IDAuMjUsIG9ubHkucG9zID0gVFJVRSwgdGhyZXNoLnVzZSA9IDAuMjUpCmNsdXN0ZXI2Lm1hcmtlcnMgPC0gRmluZE1hcmtlcnMob2JqZWN0ID0gdGlzcywgaWRlbnQuMSA9IDYsIG1pbi5wY3QgPSAwLjI1LCBvbmx5LnBvcyA9IFRSVUUsIHRocmVzaC51c2UgPSAwLjI1KQojY2x1c3RlcjcubWFya2VycyA8LSBGaW5kTWFya2VycyhvYmplY3QgPSB0aXNzLCBpZGVudC4xID0gNywgbWluLnBjdCA9IDAuMjUsIG9ubHkucG9zID0gVFJVRSwgdGhyZXNoLnVzZSA9IDAuMjUpCiNjbHVzdGVyOC5tYXJrZXJzIDwtIEZpbmRNYXJrZXJzKG9iamVjdCA9IHRpc3MsIGlkZW50LjEgPSA4LCBtaW4ucGN0ID0gMC4yNSwgb25seS5wb3MgPSBUUlVFLCB0aHJlc2gudXNlID0gMC4yNSkKI2NsdXN0ZXI5Lm1hcmtlcnMgPC0gRmluZE1hcmtlcnMob2JqZWN0ID0gdGlzcywgaWRlbnQuMSA9IDksIG1pbi5wY3QgPSAwLjI1LCBvbmx5LnBvcyA9IFRSVUUsIHRocmVzaC51c2UgPSAwLjI1KQojY2x1c3RlcjAubWFya2VycyA8LSBGaW5kTWFya2VycyhvYmplY3QgPSB0aXNzLCBpZGVudC4xID0gMCwgbWluLnBjdCA9IDAuMjUsIG9ubHkucG9zID0gVFJVRSwgdGhyZXNoLnVzZSA9IDAuMjUpCmBgYAoKV2hpY2ggbWFya2VycyBpZGVudGlmeSBhIHNwZWNpZmljIGNsdXN0ZXI/CmBgYHtyfQpwcmludCh4ID0gaGVhZCh4ID0gY2x1c3RlcjYubWFya2VycywgbiA9IDMwKSkKYGBgCgoKWW91IGNhbiBhbHNvIGNvbXB1dGUgYWxsIG1hcmtlcnMgZm9yIGFsbCBjbHVzdGVycyBhdCBvbmNlLiBUaGlzIG1heSB0YWtlIHNvbWUgdGltZS4KYGBge3J9CnRpc3MubWFya2VycyA8LSBGaW5kQWxsTWFya2VycyhvYmplY3QgPSB0aXNzLCBvbmx5LnBvcyA9IFRSVUUsIG1pbi5wY3QgPSAwLjI1LCB0aHJlc2gudXNlID0gMC4yNSkKYGBgCgpEaXNwbGF5IHRoZSB0b3AgbWFya2VycyB5b3UgY29tcHV0ZWQgYWJvdmUuCmBgYHtyfQp0aXNzLm1hcmtlcnMgJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSB0b3BfbigyMCwgYXZnX2xvZ0ZDKQpgYGAKCgpHZW5lcmF0ZSBhbiBleHByZXNzaW9uIGhlYXRtYXAgZm9yIGdpdmVuIGNlbGxzIGFuZCBnZW5lcy4gSW4gdGhpcyBjYXNlLCB3ZSBhcmUgcGxvdHRpbmcgdGhlIHRvcCAyMCBtYXJrZXJzIChvciBhbGwgbWFya2VycyBpZiBsZXNzIHRoYW4gMjApIGZvciBlYWNoIGNsdXN0ZXIuCmBgYHtyLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTUwLCBmaWcud2lkdGg9MzV9CiN0b3AxMCA8LSB0aXNzLm1hcmtlcnMgJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSB0b3BfbigxMCwgYXZnX2xvZ0ZDKQp0b3AyMCA8LSB0aXNzLm1hcmtlcnMgJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSB0b3BfbigyMCwgYXZnX2xvZ0ZDKQojIHNldHRpbmcgc2xpbS5jb2wubGFiZWwgdG8gVFJVRSB3aWxsIHByaW50IGp1c3QgdGhlIGNsdXN0ZXIgSURTIGluc3RlYWQgb2YKIyBldmVyeSBjZWxsIG5hbWUKRG9IZWF0bWFwKHRpc3MsIGdlbmVzLnVzZSA9IHRvcDIwJGdlbmUsIHNsaW0uY29sLmxhYmVsID0gVFJVRSwgcmVtb3ZlLmtleSA9IFRSVUUsIGNleC5yb3cgPSAyMCwgZ3JvdXAuY2V4ID0gMjAgKQpgYGAKCgoKIyMgQXNzaWduaW5nIGNlbGwgdHlwZSBpZGVudGl0eSB0byBjbHVzdGVycwoKQXQgYSBjb2Fyc2UgbGV2ZWwsIHdlIGNhbiB1c2UgY2Fub25pY2FsIG1hcmtlcnMgdG8gbWF0Y2ggdGhlIHVuYmlhc2VkIGNsdXN0ZXJpbmcgdG8ga25vd24gY2VsbCB0eXBlczoKQ2x1c3RlciAwOiBiYXNhbCBjZWxsIG9mIGVwaWRlcm1pcyAoQ0w6MDAwMjE4NykKQ2x1c3RlciAxOiBkaWZmZXJlbnRpYXRlZCBrZXJhdGlub2N5dGVzIChDTDowMDAwMzEyKQpDbHVzdGVyIDI6IHByb2xpZmVyYXRpbmcgYmFzYWwgY2VsbCBvZiBlcGlkZXJtaXMgKENMOjAwMDIxODcpCkNsdXRzZXIgMzogc3VwcmFiYXNhbCBkaWZmZXJlbnRpYXRpbmcga2VyYXRpbm9jeXRlcyAgKENMOjAwMDAzMTIpCkNsdXN0ZXIgNDogYmFzYWwgY2VsbCBvZiBlcGlkZXJtaXMgKENMOjAwMDIxODcpCkNsdXN0ZXIgNTogc3VwcmFiYXNhbCBkaWZmZXJlbnRpYXRlZCBrZXJhdGlub2N5dGVzIChDTDowMDAwMzEyKQpDbHVzdGVyIDY6IGJhc2FsIGNlbGwgb2YgZXBpZGVybWlzIChDTDowMDAyMTg3KQpDbHVzdGVyIDc6IGJhc2FsIGNlbGwgb2YgZXBpZGVybWlzIChDTDowMDAyMTg3KQpDbHV0c2VyIDg6IGJhc2FsIGNlbGwgb2YgZXBpZGVybWlzIChDTDowMDAyMTg3KQpDbHVzdGVyIDk6IGZpbGlmb3JtIGRpZmZlcmVudGlhdGVkIGtlcmF0aW5vY3l0ZXMgKENMOjAwMDAzMTIpCkNsdXN0ZXIgMTA6IExhbmdlcmhhbnMgY2VsbHMgKENMXzAwMDA0NTMpCmBgYHtyfQojIHN0YXNoIGN1cnJlbnQgY2x1c3RlciBJRHMKdGlzcyA8LSBTdGFzaElkZW50KG9iamVjdCA9IHRpc3MsIHNhdmUubmFtZSA9ICJjbHVzdGVyLmlkcyIpCgojIGVudW1lcmF0ZSBjdXJyZW50IGNsdXN0ZXIgSURzIGFuZCB0aGUgbGFiZWxzIGZvciB0aGVtCmNsdXN0ZXIuaWRzIDwtIGMoMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTApCmZyZWVfY2VsbF9vbnRvbG9neV9pZCA8LSBjKCJiYXNhbF9jZWxscyIsICJkaWZmZXJlbnRpYXRlZCIsICJwcm9saWZlcmF0aW5nIiwic3VwcmFiYXNhbF9kaWZmZXJlbnRpYXRpbmciLCAiYmFzYWxfY2VsbHMiLCJzdXByYWJhc2FsX2RpZmZlcmVudGlhdGVkIiwgImJhc2FsX2NlbGxzIiwgImJhc2FsX2NlbGxzIiwgImJhc2FsX2NlbGxzIiwgImZpbGlmb3JtX2RpZmZlcmVudGlhdGVkIiwgIkxhbmdlcmhhbnMgY2VsbHMiKQpjZWxsX29udG9sb2d5X2NsYXNzIDwtIGMoIkNMOjAwMDIxODciLCAiQ0w6MDAwMDMxMiIsICJDTDowMDAyMTg3IiwgIkNMOjAwMDAzMTIiLCAiQ0w6MDAwMjE4NyIsICJDTDowMDAwMzEyIiwgIkNMOjAwMDIxODciLCAiQ0w6MDAwMjE4NyIsICJDTDowMDAyMTg3IiwgIkNMOjAwMDAzMTIiLCAnQ0xfMDAwMDQ1MycpCmNlbGxfb250b2xvZ3lfaWQgPC0gYygiQ0w6MDAwMjE4NyIsICJDTDowMDAwMzEyIiwgIkNMOjAwMDIxODciLCAiQ0w6MDAwMDMxMiIsICJDTDowMDAyMTg3IiwgIkNMOjAwMDAzMTIiLCAiQ0w6MDAwMjE4NyIsICJDTDowMDAyMTg3IiwgIkNMOjAwMDIxODciLCAiQ0w6MDAwMDMxMnMiLCAnQ0xfMDAwMDQ1MycpCgojc3ViY2VsbF9vbnRvbG9neV9jbGFzcyA9IGMoImRpZmZlcmVudGlhdGluZyIsICJkaWZmZXJlbnRpYXRpbmciLCAiZGlmZmVyZW50aWF0aW5nIiwgInByb2xpZmVyYXRpbmciLCAiZGlmZmVyZW50aWF0aW5nIiwgImRpZmZlcmVudGlhdGluZyIsICJkaWZmZXJlbnRpYXRpbmciLCAiZGlmZmVyZW50aWF0aW5nIiwgIkZpbGlmb3JtIiwgTkEpCgpjZWxsX29udG9sb2d5X2NsYXNzLnN1YmNlbGxfb250b2xvZ3lfY2xhc3MgPSBwYXN0ZTAoY2VsbF9vbnRvbG9neV9jbGFzcywnOiAnLCBmcmVlX2NlbGxfb250b2xvZ3lfaWQpCgp0aXNzQG1ldGEuZGF0YVssJ2NlbGxfb250b2xvZ3lfY2xhc3MnXSA8LSBwbHlyOjptYXB2YWx1ZXMoeCA9IHRpc3NAaWRlbnQsIGZyb20gPSBjbHVzdGVyLmlkcywgdG8gPSBjZWxsX29udG9sb2d5X2NsYXNzKQp0aXNzQG1ldGEuZGF0YVssJ2NlbGxfb250b2xvZ3lfaWQnXSA8LSBwbHlyOjptYXB2YWx1ZXMoeCA9IHRpc3NAaWRlbnQsIGZyb20gPSBjbHVzdGVyLmlkcywgdG8gPSBjZWxsX29udG9sb2d5X2lkKQoKdGlzc0BtZXRhLmRhdGFbdGlzc0BjZWxsLm5hbWVzLCdjZWxsX29udG9sb2d5X2NsYXNzJ10gPC0gYXMuY2hhcmFjdGVyKHRpc3NAbWV0YS5kYXRhJGNlbGxfb250b2xvZ3lfY2xhc3MpCnRpc3NAbWV0YS5kYXRhW3Rpc3NAY2VsbC5uYW1lcywnY2VsbF9vbnRvbG9neV9pZCddIDwtIGFzLmNoYXJhY3Rlcih0aXNzQG1ldGEuZGF0YSRjZWxsX29udG9sb2d5X2lkKQoKdGlzc0BtZXRhLmRhdGFbLCdzdWJjZWxsX29udG9sb2d5X2NsYXNzJ10gPC0gcGx5cjo6bWFwdmFsdWVzKHggPSB0aXNzQG1ldGEuZGF0YSRjbHVzdGVyLmlkcywgZnJvbSA9IGNsdXN0ZXIuaWRzLCB0byA9IGZyZWVfY2VsbF9vbnRvbG9neV9pZCkKdGlzc0BtZXRhLmRhdGFbLCdjZWxsX29udG9sb2d5X2NsYXNzLnN1YmNlbGxfb250b2xvZ3lfY2xhc3MnXSA8LSBwbHlyOjptYXB2YWx1ZXMoeCA9IHRpc3NAbWV0YS5kYXRhJGNsdXN0ZXIuaWRzLCBmcm9tID0gY2x1c3Rlci5pZHMsIHRvID0gY2VsbF9vbnRvbG9neV9jbGFzcy5zdWJjZWxsX29udG9sb2d5X2NsYXNzKQoKVFNORVBsb3Qob2JqZWN0ID0gdGlzcywgZG8ubGFiZWwgPSBUUlVFLCBwdC5zaXplID0gMC41LCBncm91cC5ieT0nY2VsbF9vbnRvbG9neV9jbGFzcycpClRTTkVQbG90KG9iamVjdCA9IHRpc3MsIGRvLmxhYmVsID0gVFJVRSwgcHQuc2l6ZSA9IDAuNSwgZ3JvdXAuYnk9J2NlbGxfb250b2xvZ3lfY2xhc3Muc3ViY2VsbF9vbnRvbG9neV9jbGFzcycpCmBgYAoKCiMjIENoZWNraW5nIGZvciBiYXRjaCBlZmZlY3RzCgoKQ29sb3IgYnkgbWV0YWRhdGEsIGxpa2UgcGxhdGUgYmFyY29kZSwgdG8gY2hlY2sgZm9yIGJhdGNoIGVmZmVjdHMuCmBgYHtyfQpUU05FUGxvdChvYmplY3QgPSB0aXNzLCBkby5yZXR1cm4gPSBUUlVFLCBncm91cC5ieSA9ICJjaGFubmVsIikKYGBgCgpgYGB7cn0KVFNORVBsb3Qob2JqZWN0ID0gdGlzcywgZG8ucmV0dXJuID0gVFJVRSwgZ3JvdXAuYnkgPSAibW91c2Uuc2V4IikKYGBgCgpQcmludCBhIHRhYmxlIHNob3dpbmcgdGhlIGNvdW50IG9mIGNlbGxzIGluIGVhY2ggaWRlbnRpdHkgY2F0ZWdvcnkgZnJvbSBlYWNoIHBsYXRlLgoKYGBge3J9CnRhYmxlKGFzLmNoYXJhY3Rlcih0aXNzQGlkZW50KSwgYXMuY2hhcmFjdGVyKHRpc3NAbWV0YS5kYXRhJGNoYW5uZWwpKQpgYGAKCiMgU2F2ZSB0aGUgUm9iamVjdCBmb3IgbGF0ZXIKV2hlbiB5b3Ugc2F2ZSB0aGUgYW5ub3RhdGVkIHRpc3N1ZSwgcGxlYXNlIGdpdmUgaXQgYSBuYW1lLgoKYGBge3J9CmZpbGVuYW1lID0gaGVyZSgnMDBfZGF0YV9pbmdlc3QnLCAnMDRfdGlzc3VlX3JvYmpfZ2VuZXJhdGVkJywgCgkJICBwYXN0ZTAoImRyb3BsZXQiLCB0aXNzdWVfb2ZfaW50ZXJlc3QsICJfc2V1cmF0X3Rpc3MuUm9iaiIpKQpwcmludChmaWxlbmFtZSkKc2F2ZSh0aXNzLCBmaWxlPWZpbGVuYW1lKQpgYGAKCmBgYHtyfQojIFRvIHJlbG9hZCBhIHNhdmVkIG9iamVjdAojIGZpbGVuYW1lID0gaGVyZSgnMDBfZGF0YV9pbmdlc3QnLCAnMDRfdGlzc3VlX3JvYmpfZ2VuZXJhdGVkJywgCiMgICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKCJmYWNzIiwgdGlzc3VlX29mX2ludGVyZXN0LCAiX3NldXJhdF90aXNzLlJvYmoiKSkKIyBsb2FkKGZpbGU9ZmlsZW5hbWUpCmBgYAoKCgojIEV4cG9ydCB0aGUgZmluYWwgbWV0YWRhdGEKClNvIHRoYXQgQmlvaHViIGNhbiBlYXNpbHkgY29tYmluZSBhbGwgeW91ciBjZWxsX29udG9sb2d5X2NsYXNzcywgcGxlYXNlIGV4cG9ydCB0aGVtIGFzIGEgc2ltcGxlIGNzdi4KCmBgYHtyfQpoZWFkKHRpc3NAbWV0YS5kYXRhKQpgYGAKCgpgYGB7cn0KZmlsZW5hbWUgPSBoZXJlKCcwMF9kYXRhX2luZ2VzdCcsICcwM190aXNzdWVfYW5ub3RhdGlvbl9jc3YnLCAKCQkgIHBhc3RlMCh0aXNzdWVfb2ZfaW50ZXJlc3QsICJfZHJvcGxldF9jZWxsX29udG9sb2d5X2NsYXNzLmNzdiIpKQp3cml0ZS5jc3YodGlzc0BtZXRhLmRhdGFbLGMoJ2NoYW5uZWwnLCdjZWxsX29udG9sb2d5X2NsYXNzJywnY2VsbF9vbnRvbG9neV9jbGFzcy5zdWJjZWxsX29udG9sb2d5X2NsYXNzJyldLCBmaWxlPWZpbGVuYW1lKQpgYGAK